home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1993 / Internet Info CD-ROM (Walnut Creek) (1993).iso / standards / misc / Electronic.Arts.IFF < prev    next >
Encoding:
Internet Message Format  |  1993-07-15  |  178.1 KB

  1. From peter@sugar.hackercorp.com Tue Dec 11 20:33:09 1990
  2. From: peter@sugar.hackercorp.com (Peter da Silva)
  3. Newsgroups: alt.binaries.multimedia
  4. Subject: Definition of Electronic Arts IFF format
  5. Date: 10 Dec 90 12:56:36 GMT
  6. Reply-To: peter@sugar.hackercorp.com (Peter da Silva)
  7. Organization: Sugar Land Unix - Houston
  8.  
  9. In a radical move, infomation instead of flames.
  10.  
  11. Definitions of the Electronic Arts IFF formats for text, sampled sounds,
  12. musical scores, and images.
  13.  
  14. : This archive contains the following files...
  15. : '8svx'
  16. : 'ea.iff.85'
  17. : 'ftxt'
  18. : 'ilbm'
  19. : 'smus'
  20. : To extract them, run the following through /bin/sh
  21. echo x - 8svx
  22. sed 's/^X//' > 8svx << '//END'
  23. X"8SVX" IFF 8-Bit Sampled Voice
  24. X
  25. XDate:    February 7, 1985
  26. XFrom:    Steve Hayes and Jerry Morrison, Electronic Arts
  27. XStatus:    Adopted
  28. X
  29. X1. Introduction
  30. X
  31. XThis memo is the IFF supplement for FORM "8SVX". An 8SVX is an IFF 
  32. X"data section" or "FORM" (which can be an IFF file or a part of one) 
  33. Xcontaining a digitally sampled audio voice consisting of 8-bit samples. 
  34. XA voice can be a one-shot sound orQwith repetition and pitch scalingQa 
  35. Xmusical instrument. "EA IFF 85" is Electronic Arts' standard interchange 
  36. Xfile format. [See "EA IFF 85" Standard for Interchange Format Files.]
  37. X
  38. XThe 8SVX format is designed for playback hardware that uses 8-bit 
  39. Xsamples attenuated by a volume control for good overall signal-to-noise 
  40. Xratio. So a FORM 8SVX stores 8-bit samples and a volume level.
  41. X
  42. XA similar data format (or two) will be needed for higher resolution 
  43. Xsamples (typically 12 or 16 bits). Properly converting a high resolution 
  44. Xsample down to 8 bits requires one pass over the data to find the 
  45. Xminimum and maximum values and a second pass to scale each sample 
  46. Xinto the range -128 through 127. So it's reasonable to store higher 
  47. Xresolution data in a different FORM type and convert between them.
  48. X
  49. XFor instruments, FORM 8SVX can record a repeating waveform optionally 
  50. Xpreceded by a startup transient waveform. These two recorded signals 
  51. Xcan be pre-synthesized or sampled from an acoustic instrument. For 
  52. Xmany instruments, this representation is compact. FORM 8SVX is less 
  53. Xpractical for an instrument whose waveform changes from cycle to cycle 
  54. Xlike a plucked string, where a long sample is needed for accurate 
  55. Xresults.
  56. X
  57. XFORM 8SVX can store an "envelope" or "amplitude contour" to enrichen 
  58. Xmusical notes. A future voice FORM could also store amplitude, frequency, 
  59. Xand filter modulations.
  60. X
  61. XFORM 8SVX is geared for relatively simple musical voices, where one 
  62. Xwaveform per octave is sufficient, where the waveforms for the different 
  63. Xoctaves follows a factor-of-two size rule, and where one envelope 
  64. Xis adequate for all octaves. You could store a more general voice 
  65. Xas a LIST containing one or more FORMs 8SVX per octave. A future voice 
  66. XFORM could go beyond one "one-shot" waveform and one "repeat" waveform 
  67. Xper octave.
  68. X
  69. XSection 2 defines the required property sound header "VHDR", optional 
  70. Xproperties name "NAME", copyright "(c)J", and author "AUTH", the optional 
  71. Xannotation data chunk "ANNO", the required data chunk "BODY", and 
  72. Xoptional envelope chunks "ATAK" and "RLSE". These are the "standard" 
  73. Xchunks. Specialized chunks for private or future needs can be added 
  74. Xlater, e.g. to hold a frequency contour or Fourier series coefficients. 
  75. XThe 8SVX syntax is summarized in Appendix A as a regular expression 
  76. Xand in Appendix B as an example box diagram. Appendix C explains the 
  77. Xoptional Fibonacci-delta compression algorithm.
  78. X
  79. XCaution: The VHDR structure Voice8Header changed since draft proposal 
  80. X#4! The new structure is incompatible with the draft version.
  81. X
  82. X
  83. X
  84. XReference:
  85. X
  86. X"EA IFF 85" Standard for Interchange Format Files describes the underlying 
  87. Xconventions for all IFF files.
  88. X
  89. XAmiga[tm] is a trademark of Commodore-Amiga, Inc.
  90. X
  91. XElectronic Arts[tm] is a trademark of Electronic Arts.
  92. X
  93. XMacWrite[tm] is a trademark of Apple Computer, Inc.
  94. X
  95. X
  96. X
  97. X2. Standard Data and Property Chunks
  98. X
  99. XFORM 8SVX stores all the waveform data in one body chunk "BODY". It 
  100. Xstores playback parameters in the required header chunk "VHDR". "VHDR" 
  101. Xand any optional property chunks "NAME", "(c)J", and "AUTH" must all 
  102. Xappear before the BODY chunk. Any of these properties may be shared 
  103. Xover a LIST of FORMs 8SVX by putting them in a PROP 8SVX. [See "EA 
  104. XIFF 85" Standard for Interchange Format Files.]
  105. X
  106. XBackground
  107. X
  108. XThere are two ways to use FORM 8SVX: as a one-shot sampled sound or 
  109. Xas a sampled musical instrument that plays "notes". Storing both kinds 
  110. Xof sounds in the same kind of FORM makes it easy to play a one-shot 
  111. Xsound as a (staccato) instrument or an instrument as a (one-note) 
  112. Xsound.
  113. X
  114. XA one-shot sound is a series of audio data samples with a nominal 
  115. Xplayback rate and amplitude. The recipient program can optionally 
  116. Xadjust or modulate the amplitude and playback data rate.
  117. X
  118. XFor musical instruments, the idea is to store a sampled (or pre-synthesized) 
  119. Xwaveform that will be parameterized by pitch, duration, and amplitude 
  120. Xto play each "note". The creator of the FORM 8SVX can supply a waveform 
  121. Xper octave over a range of octaves for this purpose. The intent is 
  122. Xto perform a pitch by selecting the closest octave's waveform and 
  123. Xscaling the playback data rate. An optional "one-shot" waveform supplies 
  124. Xan arbitrary startup transient, then a "repeat" waveform is iterated 
  125. Xas long as necessary to sustain the note.
  126. X
  127. XA FORM 8SVX can also store an envelope to modulate the waveform. Envelopes 
  128. Xare mostly useful for variable-duration notes but could be used for 
  129. Xone-shot sounds, too.
  130. X
  131. XThe FORM 8SVX standard has some restrictions. For example, each octave 
  132. Xof data must be twice as long as the next higher octave. Most sound 
  133. Xdriver software and hardware imposes additional restrictions. E.g. 
  134. Xthe Amiga sound hardware requires an even number of samples in each 
  135. Xone-shot and repeat waveform.
  136. X
  137. XRequired Property VHDR
  138. X
  139. XThe required property "VHDR" holds a Voice8Header structure as defined 
  140. Xin these C declarations and following documentation. This structure 
  141. Xholds the playback parameters for the sampled waveforms in the BODY 
  142. Xchunk. (See "Data Chunk BODY", below, for the storage layout of these 
  143. Xwaveforms.)
  144. X
  145. X#define ID_8SVX MakeID('8', 'S', 'V', 'X')
  146. X#define ID_VHDR MakeID('V', 'H', 'D', 'R')
  147. X
  148. Xtypedef LONG Fixed;    
  149. X    /* A fixed-point value, 16 bits to the left of the point and 16 
  150. X     * to the right. A Fixed is a number of 216ths, i.e. 65536ths.    */
  151. X
  152. X#define Unity 0x10000L    /* Unity = Fixed 1.0 = maximum volume    */
  153. X
  154. X/* sCompression: Choice of compression algorithm applied to the samples. */ 
  155. X
  156. X#define sCmpNone       0    /* not compressed    */
  157. X#define sCmpFibDelta   1    /* Fibonacci-delta encoding (Appendix C)  */ 
  158. X
  159. X/* Can be more kinds in the future.    */
  160. X
  161. Xtypedef struct {
  162. X    ULONG oneShotHiSamples,    /* # samples in the high octave 1-shot part */
  163. X        repeatHiSamples,    /* # samples in the high octave repeat part */
  164. X        samplesPerHiCycle;    /* # samples/cycle in high octave, else 0   */
  165. X    UWORD samplesPerSec;    /* data sampling rate    */
  166. X    UBYTE ctOctave,        /* # octaves of waveforms    */
  167. X          sCompression;        /* data compression technique used    */
  168. X    Fixed volume;        /* playback volume from 0 to Unity (full 
  169. X                 * volume). Map this value into the output 
  170. X                 * hardware's dynamic range.    */
  171. X    } Voice8Header;
  172. X
  173. X[Implementation details. Fields are filed in the order shown. The 
  174. XUBYTE fields are byte-packed (2 per 16-bit word). MakeID is a C macro 
  175. Xdefined in the main IFF document and in the source file IFF.h.]
  176. X
  177. XA FORM 8SVX holds waveform data for one or more octaves, each containing 
  178. Xa one-shot part and a repeat part. The fields oneShotHiSamples and 
  179. XrepeatHiSamples tell the number of audio samples in the two parts 
  180. Xof the highest frequency octave. Each successive (lower frequency) 
  181. Xoctave contains twice as many data samples in both its one-shot and 
  182. Xrepeat parts. One of these two parts can be empty across all octaves.
  183. X
  184. XNote: Most audio output hardware and software has limitations. The 
  185. XAmiga computer's sound hardware requires that all one-shot and repeat 
  186. Xparts have even numbers of samples. Amiga sound driver software would 
  187. Xhave to adjust an odd-sized waveform, ignore an odd-sized lowest octave, 
  188. Xor ignore odd FORMs 8SVX altogether. Some other output devices require 
  189. Xall sample sizes to be powers of two.
  190. X
  191. XThe field samplesPerHiCycle tells the number of samples/cycle in the 
  192. Xhighest frequency octave of data, or else 0 for "unknown". Each successive 
  193. X(lower frequency) octave contains twice as many samples/cycle. The 
  194. XsamplesPerHiCycle value is needed to compute the data rate for a desired 
  195. Xplayback pitch.
  196. X
  197. XActually, samplesPerHiCycle is an average number of samples/cycle. 
  198. XIf the one-shot part contains pitch bends, store the samples/cycle 
  199. Xof the repeat part in samplesPerHiCycle. The division repeatHiSamples/samplesPe
  200. XrHiCycle should yield an integer number of cycles. (When the repeat 
  201. Xwaveform is repeated, a partial cycle would come out as a higher-frequency 
  202. Xcycle with a "click".)
  203. X
  204. XMore limitations: Some Amiga music drivers require samplesPerHiCycle 
  205. Xto be a power of two in order to play the FORM 8SVX as a musical instrument 
  206. Xin tune. They may even assume samplesPerHiCycle is a particular power 
  207. Xof two without checking. (If samplesPerHiCycle is different by a factor 
  208. Xof two, the instrument will just be played an octave too low or high.)
  209. X
  210. XThe field samplesPerSec gives the sound sampling rate. A program may 
  211. Xadjust this to achieve frequency shifts or vary it dynamically to 
  212. Xachieve pitch bends and vibrato. A program that plays a FORM 8SVX 
  213. Xas a musical instrument would ignore samplesPerSec and select a playback 
  214. Xrate for each musical pitch.
  215. X
  216. XThe field ctOctave tells how many octaves of data are stored in the 
  217. XBODY chunk. See "Data Chunk BODY", below, for the layout of the octaves.
  218. X
  219. XThe field sCompression indicates the compression scheme, if any, that 
  220. Xwas applied to the entire set of data samples stored in the BODY chunk. 
  221. XThis field should contain one of the values defined above. Of course, 
  222. Xthe matching decompression algorithm must be applied to the BODY data 
  223. Xbefore the sound can be played. (The Fibonacci-delta encoding scheme 
  224. XsCmpFibDelta is described in Appendix C.) Note that the whole series 
  225. Xof data samples is compressed as a unit.
  226. X
  227. XThe field volume gives an overall playback volume for the waveforms 
  228. X(all octaves). It lets the 8-bit data samples use the full range -128 
  229. Xthrough 127 for good signal-to-noise ratio and be attenuated on playback 
  230. Xto the desired level. The playback program should multiply this value 
  231. Xby a "volume control" and perhaps by a playback envelope (see ATAK 
  232. Xand RLSE, below).
  233. X
  234. XRecording a one-shot sound. To store a one-shot sound in a FORM 8SVX, 
  235. Xset oneShotHiSamples = number of samples, repeatHiSamples = 0 , 
  236. XsamplesPerHiCycle = 0, samplesPerSec = sampling rate, and ctOctave = 1. 
  237. XScale the signal amplitude to the full sampling range -128 through 127. Set 
  238. Xvolume so the sound will playback at the desired volume level. If 
  239. Xyou set the samplesPerHiCycle field properly, the data can also be 
  240. Xused as a musical instrument.
  241. X
  242. XExperiment with data compression. If the decompressed signal sounds 
  243. Xok, store the compressed data in the BODY chunk and set sCompression 
  244. Xto the compression code number.
  245. X
  246. XRecording a musical instrument. To store a musical instrument in a 
  247. XFORM 8SVX, first record or synthesize as many octaves of data as you 
  248. Xwant to make available for playback. Set ctOctaves to the count of 
  249. Xoctaves. From the recorded data, excerpt an integral number of steady 
  250. Xstate cycles for the repeat part and set repeatHiSamples and samplesPerHiCycle. 
  251. XEither excerpt a startup transient waveform and set oneShotHiSamples, 
  252. Xor else set oneShotHiSamples to 0. Remember, the one-shot and repeat 
  253. Xparts of each octave must be twice as long as those of the next higher 
  254. Xoctave. Scale the signal amplitude to the full sampling range and 
  255. Xset volume to adjust the instrument playback volume. If you set the 
  256. XsamplesPerSec field properly, the data can also be used as a one-shot 
  257. Xsound.
  258. X
  259. XA distortion-introducing compressor like sCmpFibDelta is not recommended 
  260. Xfor musical instruments, but you might try it anway.
  261. X
  262. XTypically, creators of FORM 8SVX record an acoustic instrument at 
  263. Xjust one frequency. Decimate (down- sample with filtering) to compute 
  264. Xhigher octaves. Interpolate to compute lower octaves.
  265. X
  266. XIf you sample an acoustic instrument at different octaves, you may 
  267. Xfind it hard to make the one-shot and repeat waveforms follow the 
  268. Xfactor-of-two rule for octaves. To compensate, lengthen an octave's 
  269. Xone-shot part by appending replications of the repeating cycle or 
  270. Xprepending zeros. (This will have minimal impact on the sound's start 
  271. Xtime.) You may be able to equalize the ratio one-shot-samples : repeat-samples 
  272. Xacross all octaves.
  273. X
  274. XNote that a "one-shot sound" may be played as a "musical instrument" 
  275. Xand vice versa. However, an instrument player depends on samplesPerHiCycle, 
  276. Xand a one-shot player depends on samplesPerSec.
  277. X
  278. XPlaying a one-shot sound. To play any FORM 8SVX data as a one-shot 
  279. Xsound, first select an octave if ctOctave > 1. (The lowest-frequency 
  280. Xoctave has the greatest resolution.) Play the one-shot samples then 
  281. Xthe repeat samples, scaled by volume, at a data rate of samplesPerSec. 
  282. XOf course, you may adjust the playback rate and volume. You can play 
  283. Xout an envelope, too. (See ATAK and RLSE, below.)
  284. X
  285. XPlaying a musical note. To play a musical note using any FORM 8SVX, 
  286. Xfirst select the nearest octave of data from those available. Play 
  287. Xthe one-shot waveform then cycle on the repeat waveform as long as 
  288. Xneeded to sustain the note. Scale the signal by volume, perhaps also 
  289. Xby an envelope, and by a desired note volume. Select a playback data 
  290. Xrate s samples/second to achieve the desired frequency (in Hz):
  291. Xfrequency = sJ/JsamplesPerHiCycle
  292. Xfor the highest frequency octave.
  293. X
  294. XThe idea is to select an octave and one of 12 sampling rates (assuming 
  295. Xa 12-tone scale). If the FORM 8SVX doesn't have the right octave, 
  296. Xyou can decimate or interpolate from the available data.
  297. X
  298. XWhen it comes to musical instruments, FORM 8SVX is geared for a simple 
  299. Xsound driver. Such a driver uses a single table of 12 data rates to 
  300. Xreach all notes in all octaves. That's why 8SVX requires each octave 
  301. Xof data to have twice as many samples as the next higher octave. If 
  302. Xyou restrict samplesPerHiCycle to a power of two, you can use a predetermined 
  303. Xtable of data rates.
  304. X
  305. XOptional Text Chunks NAME, (c), AUTH, ANNO
  306. X
  307. XSeveral text chunks may be included in a FORM 8SVX to keep ancillary 
  308. Xinformation.
  309. X
  310. XThe optional property "NAME" names the voice, for instance "tubular 
  311. Xbells".
  312. X
  313. XThe optional property "(c)J" holds a copyright notice for the voice. 
  314. XThe chunk ID "(c)J" serves as the copyright characters ")J". E.g. 
  315. Xa "(c)J" chunk containing "1986 Electronic Arts" means ") 1986 Electronic 
  316. XArts".
  317. X
  318. XThe optional property "AUTH" holds the name of the instrument's "author" 
  319. Xor "creator".
  320. X
  321. XThe chunk types "NAME", "(c) ", and "AUTH" are property chunks. Putting 
  322. Xmore than one NAME (or other) property in a FORM is redundant. Just 
  323. Xthe last NAME counts. A property should be shorter than 256 characters. 
  324. XProperties can appear in a PROP 8SVX to share them over a LIST of 
  325. XFORMs 8SVX.
  326. X
  327. XThe optional data chunk "ANNO" holds any text annotations typed in 
  328. Xby the author.
  329. X
  330. XAn ANNO chunk is not a property chunk, so you can put more than one 
  331. Xin a FORM 8SVX. You can make ANNO chunks any length up to 231 - 1 
  332. Xcharacters, but 32767 is a practical limit. Since they're not properties, 
  333. XANNO chunks don't belong in a PROP 8SVX. That means they can't be 
  334. Xshared over a LIST of FORMs 8SVX.
  335. X
  336. XSyntactically, each of these chunks contains an array of 8-bit ASCII 
  337. Xcharacters in the range " " (SP, hex 20) through "~" (tilde, hex 7F), 
  338. Xjust like a standard "TEXT" chunk. [See "Strings, String Chunks, and 
  339. XString Properties" in "EA IFF 85" Electronic Arts Interchange File 
  340. XFormat.] The chunk's ckSize field holds the count of characters.
  341. X
  342. X#define ID_NAME MakeID('N', 'A', 'M', 'E')
  343. X/* NAME chunk contains a CHAR[], the voice's name.    */
  344. X
  345. X#define ID_Copyright MakeID('(', 'c', ')', ' ')
  346. X/* "(c) " chunk contains a CHAR[], the FORM's copyright notice.    */
  347. X
  348. X#define ID_AUTH MakeID('A', 'U', 'T', 'H')
  349. X/* AUTH chunk contains a CHAR[], the author's name.    */
  350. X
  351. X#define ID_ANNO MakeID('A', 'N', 'N', 'O')
  352. X/* ANNO chunk contains a CHAR[], author's text annotations.    */
  353. X
  354. XRemember to store a 0 pad byte after any odd-length chunk.
  355. X
  356. XOptional Data Chunks ATAK and RLSE
  357. X
  358. XThe optional data chunks ATAK and RLSE together give a piecewise-linear 
  359. X"envelope" or "amplitude contour". This contour may be used to modulate 
  360. Xthe sound during playback. It's especially useful for playing musical 
  361. Xnotes of variable durations. Playback programs may ignore the supplied 
  362. Xenvelope or substitute another.
  363. X
  364. X#define ID_ATAK MakeID('A', 'T', 'A', 'K')
  365. X#define ID_RLSE MakeID('R', 'L', 'S', 'E')
  366. X
  367. Xtypedef struct {
  368. X    UWORD duration;    /* segment duration in milliseconds, > 0    */
  369. X    Fixed dest;    /* destination volume factor    */
  370. X    } EGPoint;
  371. X
  372. X/* ATAK and RLSE chunks contain an EGPoint[], piecewise-linear envelope.*/ 
  373. X/* The envelope defines a function of time returning Fixed values. It's
  374. X * used to scale the nominal volume specified in the Voice8Header. */
  375. X
  376. XTo explain the meaning of the ATAK and RLSE chunks, we'll overview 
  377. Xthe envelope generation algorithm. Start at 0 volume, step through 
  378. Xthe ATAK contour, then hold at the sustain level (the last ATAK EGPoint's 
  379. Xdest), and then step through the RLSE contour. Begin the release at 
  380. Xthe desired note stop time minus the total duration of the release 
  381. Xcontour (the sum of the RLSE EGPoints' durations). The attack contour 
  382. Xshould be cut short if the note is shorter than the release contour.
  383. X
  384. XThe envelope is a piecewise-linear function. The envelope generator 
  385. Xinterpolates between the EGPoints.
  386. X
  387. XRemember to multiply the envelope function by the nominal voice header 
  388. Xvolume and by any desired note volume.
  389. X
  390. XFigure 1 shows an example envelope. The attack period is described 
  391. Xby 4 EGPoints in an ATAK chunk. The release period is described by 
  392. X4 EGPoints in a RLSE chunk. The sustain period in the middle just 
  393. Xholds the final ATAK level until it's time for the release.
  394. X
  395. X
  396. X
  397. X
  398. X
  399. X
  400. X
  401. X
  402. X
  403. X
  404. X            Figure 1. Amplitude contour.
  405. X
  406. XNote: The number of EGPoints in an ATAK or RLSE chunk is its ckSize 
  407. X/ sizeof(EGPoint). In RAM, the playback program may terminate the 
  408. Xarray with a 0 duration EGPoint.
  409. X
  410. XIssue: Synthesizers also provide frequency contour (pitch bend), filtering 
  411. Xcontour (wah-wah), amplitude oscillation (tremolo), frequency oscillation 
  412. X(vibrato), and filtering oscillation (leslie). In the future, we may 
  413. Xdefine optional chunks to encode these modulations. The contours can 
  414. Xbe encoded in linear segments. The oscillations can be stored as segments 
  415. Xwith rate and depth parameters.
  416. X
  417. XData Chunk BODY
  418. X
  419. XThe BODY chunk contains the audio data samples.
  420. X
  421. X#define ID_BODY MakeID('B', 'O', 'D', 'Y')
  422. X
  423. Xtypedef character BYTE;    /* 8 bit signed number, -128 through 127.    */
  424. X
  425. X/* BODY chunk contains a BYTE[], array of audio data samples.    */
  426. X
  427. XThe BODY contains data samples grouped by octave. Within each octave 
  428. Xare one-shot and repeat portions. Figure 2 depicts this arrangement 
  429. Xof samples for an 8SVX where oneShotHiSamples = 24, repeatHiSamples 
  430. X= 16, samplesPerHiCycle = 8, and ctOctave = 3. The major divisions 
  431. Xare octaves, the intermediate divisions separate the one-shot and 
  432. Xrepeat portions, and the minor divisions are cycles.
  433. X
  434. X
  435. X
  436. X
  437. X
  438. X
  439. X
  440. X
  441. X
  442. X            Figure 2. BODY subdivisions.
  443. X
  444. XIn general, the BODY has ctOctave octaves of data. The highest frequency 
  445. Xoctave comes first, comprising the fewest samples: oneShotHiSamples 
  446. X+ repeatHiSamples. Each successive octave contains twice as many samples 
  447. Xas the next higher octave but the same number of cycles. The lowest 
  448. Xfrequency octave comes last with the most samples: 2ctOctave-1 * (oneShotHiSamp
  449. Xles + repeatHiSamples).
  450. X
  451. XThe number of samples in the BODY chunk is
  452. X
  453. X  0          (ctOctave-1) 
  454. X(2  + ... + 2              * (oneShotHiSamples + repeatHiSamples)
  455. X
  456. XFigure 3, below, looks closer at an example waveform within one octave 
  457. Xof a different BODY chunk. In this example, oneShotHiSamples / samplesPerHiCycl
  458. Xe = 2 cycles and repeatHiSamples / samplesPerHiCycle = 1 cycle.
  459. X
  460. X
  461. X
  462. X
  463. X
  464. X
  465. X
  466. X
  467. X
  468. X            Figure 3. Example waveform.
  469. X
  470. XTo avoid playback "clicks", the one-shot part should begin with a 
  471. Xsmall sample value, and the one-shot part should flow smoothly into 
  472. Xthe repeat part, and the end of the repeat part should flow smoothly 
  473. Xinto the beginning of the repeat part.
  474. X
  475. XIf the VHDR field sCompression - sCmpNone, the BODY chunk is just 
  476. Xan array of data bytes to feed through the specified decompresser 
  477. Xfunction. All this stuff about sample sizes, octaves, and repeat parts 
  478. Xapplies to the decompressed data.
  479. X
  480. XBe sure to follow an odd-length BODY chunk with a 0 pad byte.
  481. X
  482. XOther Chunks
  483. X
  484. XIssue: In the future, we may define an optional chunk containing Fourier 
  485. Xseries coefficients for a repeating waveform. An editor for this kind 
  486. Xof synthesized voice could modify the coefficients and regenerate 
  487. Xthe waveform.
  488. X
  489. X
  490. X
  491. XAppendix A. Quick Reference
  492. X
  493. XType Definitions
  494. X
  495. X#define ID_8SVX MakeID('8', 'S', 'V', 'X')
  496. X#define ID_VHDR MakeID('V', 'H', 'D', 'R')
  497. X
  498. Xtypedef LONG Fixed;    /* A fixed-point value, 16 bits to the left 
  499. X             * of the point and 16 to the right. A Fixed 
  500. X             * is a number of 216ths, i.e. 65536ths. */
  501. X
  502. X#define Unity 0x10000L    /* Unity = Fixed 1.0 = maximum volume    */
  503. X
  504. X/* sCompression: Choice of compression algorithm applied to the samples    */ 
  505. X
  506. X#define sCmpNone       0    /* not compressed    */
  507. X#define sCmpFibDelta   1    /* Fibonacci-delta encoding (Appendix C) */
  508. X    /* Can be more kinds in the future.    */
  509. X
  510. Xtypedef struct {
  511. X    ULONG oneShotHiSamples,    /* # samples in the high octave 1-shot part */
  512. X        repeatHiSamples,    /* # samples in the high octave repeat part */
  513. X        samplesPerHiCycle;    /* # samples/cycle in high octave, else 0   */
  514. X    UWORD samplesPerSec;    /* data sampling rate    */
  515. X    UBYTE ctOctave,        /* # octaves of waveforms    */ 
  516. X    sCompression;        /* data compression technique used    */
  517. X    Fixed volume;        /* playback volume from 0 to Unity (full
  518. X                  * volume). Map this value into the output
  519. X                  * hardware's dynamic range.    */
  520. X    } Voice8Header;
  521. X
  522. X#define ID_NAME MakeID('N', 'A', 'M', 'E')
  523. X/* NAME chunk contains a CHAR[], the voice's name.    */
  524. X
  525. X#define ID_Copyright MakeID('(', 'c', ')', ' ')
  526. X/* "(c) " chunk contains a CHAR[], the FORM's copyright notice.    */
  527. X
  528. X#define ID_AUTH MakeID('A', 'U', 'T', 'H')
  529. X/* AUTH chunk contains a CHAR[], the author's name.    */
  530. X
  531. X#define ID_ANNO MakeID('A', 'N', 'N', 'O')
  532. X/* ANNO chunk contains a CHAR[], author's text annotations.    */
  533. X
  534. X#define ID_ATAK MakeID('A', 'T', 'A', 'K')
  535. X#define ID_RLSE MakeID('R', 'L', 'S', 'E')
  536. X
  537. Xtypedef struct {
  538. X    UWORD duration;    /* segment duration in milliseconds, > 0    */
  539. X    Fixed dest;    /* destination volume factor    */
  540. X    } EGPoint;
  541. X
  542. X/* ATAK and RLSE chunks contain an EGPoint[], piecewise-linear envelope. */
  543. X/* The envelope defines a function of time returning Fixed values. It's
  544. X * used to scale the nominal volume specified in the Voice8Header.  */
  545. X
  546. X#define ID_BODY MakeID('B', 'O', 'D', 'Y')
  547. X
  548. Xtypedef character BYTE;    /* 8 bit signed number, -128 through 127.    */
  549. X
  550. X/* BODY chunk contains a BYTE[], array of audio data samples.    */
  551. X
  552. X8SVX Regular Expression
  553. X
  554. XHere's a regular expression summary of the FORM 8SVX syntax. This 
  555. Xcould be an IFF file or part of one.
  556. X
  557. X8SVX    ::= "FORM" #{    "8SVX" VHDR [NAME] [Copyright] [AUTH] ANNO*
  558. X        [ATAK] [RLSE] BODY }
  559. X
  560. XVHDR    ::= "VHDR" #{ Voice8Header    }
  561. XNAME    ::= "NAME" #{ CHAR*    } [0]
  562. XCopyright    ::= "(c) " #{ CHAR*    } [0]
  563. XAUTH    ::= "AUTH" #{ CHAR*    } [0]
  564. XANNO    ::= "ANNO" #{ CHAR*    } [0]
  565. X
  566. XATAK    ::= "ATAK" #{ EGPoint*    }
  567. XRLSE    ::= "RLSE" #{ EGPoint*    }
  568. XBODY    ::= "FORM" #{ BYTE*    } [0]
  569. X
  570. XThe token "#" represents a ckSize LONG count of the following {braced} 
  571. Xdata bytes. E.g. a VHDR's "#" should equal sizeof(Voice8Header). Literal 
  572. Xitems are shown in "quotes", [square bracket items] are optional, 
  573. Xand "*" means 0 or more replications. A sometimes-needed pad byte 
  574. Xis shown as "[0]".
  575. X
  576. XActually, the order of chunks in a FORM 8SVX is not as strict as this 
  577. Xregular expression indicates. The property chunks VHDR, NAME, Copyright, 
  578. Xand AUTH may actually appear in any order as long as they all precede 
  579. Xthe BODY chunk. The optional data chunks ANNO, ATAK, and RLSE don't 
  580. Xhave to precede the BODY chunk. And of course, new kinds of chunks 
  581. Xmay appear inside a FORM 8SVX in the future.
  582. X
  583. X
  584. XAppendix B. 8SVX Example
  585. X
  586. XHere's a box diagram for a simple example containing the three octave 
  587. XBODY shown earlier in Figure 2.
  588. X
  589. X         +-----------------------------------+   
  590. X         |'FORM'        362              | 
  591. X          +-----------------------------------+   
  592. X          |'8SVX'                    |     
  593. X          +-----------------------------------+   
  594. X          |  +-----------------------------+  |   
  595. X          |  |'VHDR'        20       |  | 
  596. X          |  |24,16,8,10000,3,0,1.0     |  |   
  597. X          |  +-----------------------------+  |   
  598. X          |  +-----------------------------+  |   
  599. X          |  |'NAME'        11       |  |
  600. X          |  |'bass guitar'         |  |   
  601. X          |  +-----------------------------+  |   
  602. X    |  0                    |
  603. X          |  +-----------------------------+  |   
  604. X          |  |'(c)'        20       |  |
  605. X          |  |1985 Electronic Arts     |  |   
  606. X          |  +-----------------------------+  |   
  607. X          |  +-----------------------------+  |   
  608. X          |  |'BODY'        280      |  |
  609. X          |  |1, 2, 3, 4, ...         |  |   
  610. X          |  +-----------------------------+  |   
  611. X          +-----------------------------------+   
  612. X
  613. XThe "0" after the NAME chunk is a pad byte.
  614. X
  615. X
  616. X
  617. XAppendix B. Standards Committee
  618. X
  619. XThe following people contributed to the design of this IFF standard:
  620. X
  621. XBob "Kodiak" Burns, Commodore-Amiga
  622. XR. J. Mical, Commodore-Amiga
  623. XJerry Morrison, Electronic Arts
  624. XGreg Riker, Electronic Arts
  625. XSteve Shaw, Electronic Arts
  626. XBarry Walsh, Commodore-Amiga
  627. X
  628. X
  629. XThe "0" after the NAME chunk is a pad byte.
  630. X
  631. X
  632. X
  633. XAppendix C. Fibonacci Delta Compression
  634. X
  635. XThis is Steve Hayes' Fibonacci Delta sound compression technique. 
  636. XIt's like the traditional delta encoding but encodes each delta in 
  637. Xa mere 4 bits. The compressed data is half the size of the original 
  638. Xdata plus a 2-byte overhead for the initial value. This much compression 
  639. Xintroduces some distortion, so try it out and use it with discretion.
  640. X
  641. XTo achieve a reasonable slew rate, this algorithm looks up each stored 
  642. X4-bit value in a table of Fibonacci numbers. So very small deltas 
  643. Xare encoded precisely while larger deltas are approximated. When it 
  644. Xhas to make approximations, the compressor should adjust all the values 
  645. X(forwards and backwards in time) for minimum overall distortion.
  646. X
  647. XHere is the decompressor written in the C programming language.
  648. X
  649. X/* Fibonacci delta encoding for sound data. */
  650. X
  651. XBYTE codeToDelta[16] = {-34,-21,-13,-8,-5,-3,-2,-1,0,1,2,3,5,8,13,21};
  652. X
  653. X/* Unpack Fibonacci-delta encoded data from n byte source buffer into 2*n byte
  654. X * dest buffer, given initial data value x. It returns the last data value x
  655. X * so you can call it several times to incrementally decompress the data. */
  656. X
  657. Xshort D1Unpack(source, n, dest, x)
  658. X    BYTE source[], dest[];
  659. X    LONG n;
  660. X    BYTE x;
  661. X    {
  662. X    BYTE d;
  663. X    LONG i, lim;
  664. X
  665. X    lim = n <<<< 1;
  666. X    for (i = 0; i << lim; ++i)
  667. X        {    
  668. X        /* Decode a data nybble; high nybble then low nybble. */
  669. X        d = source[i >> 1];    /* get a pair of nybbles */
  670. X        if (i & 1)        /* select low or high nybble? */
  671. X            d &= 0xf;    /* mask to get the low nybble */
  672. X        else
  673. X            d >>= 4;    /* shift to get the high nybble */
  674. X        x += codeToDelta[d];    /* add in the decoded delta */
  675. X        dest[i] = x;        /* store a 1-byte sample */
  676. X        }
  677. X    return(x);
  678. X    }
  679. X
  680. X/* Unpack Fibonacci-delta encoded data from n byte source buffer into 2*(n-2)
  681. X * byte dest buffer. Source buffer has a pad byte, an 8-bit initial value,
  682. X * followed by n-2 bytes comprising 2*(n-2) 4-bit encoded samples. */
  683. X
  684. Xvoid DUnpack(source, n, dest)
  685. X    BYTE source[], dest[];
  686. X    LONG n;
  687. X    {
  688. X        D1Unpack(source + 2, n - 2, dest, source[1]);
  689. X    }
  690. //END
  691. echo x - ea.iff.85
  692. sed 's/^X//' > ea.iff.85 << '//END'
  693. X"EA IFF 85" Standard for Interchange Format Files
  694. X
  695. XDocument Date:        January 14, 1985
  696. XFrom:            Jerry Morrison, Electronic Arts
  697. XStatus of Standard:    Released and in use
  698. X
  699. X1. Introduction
  700. X
  701. XStandards are Good for Software Developers
  702. X
  703. XAs home computer hardware evolves to better and better media machines, 
  704. Xthe demand increases for higher quality, more detailed data. Data 
  705. Xdevelopment gets more expensive, requires more expertise and better 
  706. Xtools, and has to be shared across projects. Think about several ports 
  707. Xof a product on one CD-ROM with 500M Bytes of common data!
  708. X
  709. XDevelopment tools need standard interchange file formats. Imagine 
  710. Xscanning in images of "player" shapes, moving them to a paint program 
  711. Xfor editing, then incorporating them into a game. Or writing a theme 
  712. Xsong with a Macintosh score editor and incorporating it into an Amiga 
  713. Xgame. The data must at times be transformed, clipped, filled out, 
  714. Xand moved across machine kinds. Media projects will depend on data 
  715. Xtransfer from graphic, music, sound effect, animation, and script 
  716. Xtools.
  717. X
  718. XStandards are Good for Software Users
  719. X
  720. XCustomers should be able to move their own data between independently 
  721. Xdeveloped software products. And they should be able to buy data libraries 
  722. Xusable across many such products. The types of data objects to exchange 
  723. Xare open-ended and include plain and formatted text, raster and structured 
  724. Xgraphics, fonts, music, sound effects, musical instrument descriptions, 
  725. Xand animation.
  726. X
  727. XThe problem with expedient file formats typically memory dumps is 
  728. Xthat they're too provincial. By designing data for one particular 
  729. Xuse (e.g. a screen snapshot), they preclude future expansion (would 
  730. Xyou like a full page picture? a multi-page document?). In neglecting 
  731. Xthe possibility that other programs might read their data, they fail 
  732. Xto save contextual information (how many bit planes? what resolution?). 
  733. XIgnoring that other programs might create such files, they're intolerant 
  734. Xof extra data (texture palette for a picture editor), missing data 
  735. X(no color map), or minor variations (smaller image). In practice, 
  736. Xa filed representation should rarely mirror an in-memory representation. 
  737. XThe former should be designed for longevity; the latter to optimize 
  738. Xthe manipulations of a particular program. The same filed data will 
  739. Xbe read into different memory formats by different programs.
  740. X
  741. XThe IFF philosophy: "A little behind-the-scenes conversion when programs 
  742. Xread and write files is far better than NxM explicit conversion utilities 
  743. Xfor highly specialized formats."
  744. X
  745. XSo we need some standardization for data interchange among development 
  746. Xtools and products. The more developers that adopt a standard, the 
  747. Xbetter for all of us and our customers.
  748. X
  749. XHere is "EA IFF 1985"
  750. X
  751. XHere is our offering: Electronic Arts' IFF standard for Interchange 
  752. XFile Format. The full name is "EA IFF 1985". Alternatives and justifications 
  753. Xare included for certain choices. Public domain subroutine packages 
  754. Xand utility programs are available to make it easy to write and use 
  755. XIFF-compatible programs.
  756. X
  757. XPart 1 introduces the standard. Part 2 presents its requirements and 
  758. Xbackground. Parts 3, 4, and 5 define the primitive data types, FORMs, 
  759. Xand LISTs, respectively, and how to define new high level types. Part 
  760. X6 specifies the top level file structure. Appendix A is included for 
  761. Xquick reference and Appendix B names the committee responsible for 
  762. Xthis standard.
  763. X
  764. XReferences
  765. X
  766. XAmerican National Standard Additional Control Codes for Use with ASCII, 
  767. XANSI standard 3.64-1979 for an 8-bit character set. See also ISO standard 
  768. X2022 and ISO/DIS standard 6429.2.
  769. X
  770. XAmiga[tm] is a trademark of Commodore-Amiga, Inc.
  771. X
  772. XC, A Reference Manual, Samuel P. Harbison and Guy L. Steele Jr., Tartan 
  773. XLaboratories. Prentice-Hall, Englewood Cliffs, NJ, 1984.
  774. X
  775. XCompiler Construction, An Advanced Course, edited by F. L. Bauer and 
  776. XJ. Eickel (Springer-Verlag, 1976). This book is one of many sources 
  777. Xfor information on recursive descent parsing.
  778. X
  779. XDIF Technical Specification (c)1981 by Software Arts, Inc. DIF[tm] is 
  780. Xthe format for spreadsheet data interchange developed by Software 
  781. XArts, Inc.
  782. XDIF[tm] is a trademark of Software Arts, Inc.
  783. X
  784. XElectronic Arts[tm] is a trademark of Electronic Arts.
  785. X
  786. X"FTXT" IFF Formatted Text, from Electronic Arts. IFF supplement document 
  787. Xfor a text format.
  788. X
  789. XInside Macintosh (c) 1982, 1983, 1984, 1985 Apple Computer, Inc., a 
  790. Xprogrammer's reference manual.
  791. XApple(R) is a trademark of Apple Computer, Inc.
  792. XMacintosh[tm] is a trademark licensed to Apple Computer, Inc.
  793. X
  794. X"ILBM" IFF Interleaved Bitmap, from Electronic Arts. IFF supplement 
  795. Xdocument for a raster image format.
  796. X
  797. XM68000 16/32-Bit Microprocessor Programmer's Reference Manual(c) 1984, 
  798. X1982, 1980, 1979 by Motorola, Inc.
  799. X
  800. XPostScript Language Manual (c) 1984 Adobe Systems Incorporated.
  801. XPostScript[tm] is a trademark of Adobe Systems, Inc.
  802. XTimes and Helvetica(R) are trademarks of Allied Corporation.
  803. X
  804. XInterScript: A Proposal for a Standard for the Interchange of Editable 
  805. XDocuments (c)1984 Xerox Corporation.
  806. XIntroduction to InterScript (c) 1985 Xerox Corporation.
  807. X
  808. X
  809. X
  810. X2. Background for Designers
  811. X
  812. XPart 2 is about the background, requirements, and goals for the standard. 
  813. XIt's geared for people who want to design new types of IFF objects. 
  814. XPeople just interested in using the standard may wish to skip this 
  815. Xpart.
  816. X
  817. XWhat Do We Need?
  818. X
  819. XA standard should be long on prescription and short on overhead. It 
  820. Xshould give lots of rules for designing programs and data files for 
  821. Xsynergy. But neither the programs nor the files should cost too much 
  822. Xmore than the expedient variety. While we're looking to a future with 
  823. XCD-ROMs and perpendicular recording, the standard must work well on 
  824. Xfloppy disks.
  825. X
  826. XFor program portability, simplicity, and efficiency, formats should 
  827. Xbe designed with more than one implementation style in mind. (In practice, 
  828. Xpure stream I/O is adequate although random access makes it easier 
  829. Xto write files.) It ought to be possible to read one of many objects 
  830. Xin a file without scanning all the preceding data. Some programs need 
  831. Xto read and play out their data in real time, so we need good compromises 
  832. Xbetween generality and efficiency.
  833. X
  834. XAs much as we need standards, they can't hold up product schedules. 
  835. XSo we also need a kind of decentralized extensibility where any software 
  836. Xdeveloper can define and refine new object types without some "standards 
  837. Xauthority" in the loop. Developers must be able to extend existing 
  838. Xformats in a forward- and backward-compatible way. A central repository 
  839. Xfor design information and example programs can help us take full 
  840. Xadvantage of the standard.
  841. X
  842. XFor convenience, data formats should heed the restrictions of various 
  843. Xprocessors and environments. E.g. word-alignment greatly helps 68000 
  844. Xaccess at insignificant cost to 8088 programs.
  845. X
  846. XOther goals include the ability to share common elements over a list 
  847. Xof objects and the ability to construct composite objects containing 
  848. Xother data objects with structural information like directories.
  849. X
  850. XAnd finally, "Simple things should be simple and complex things should 
  851. Xbe possible."    Alan Kay.
  852. X
  853. XThink Ahead
  854. X
  855. XLet's think ahead and build programs that read and write files for 
  856. Xeach other and for programs yet to be designed. Build data formats 
  857. Xto last for future computers so long as the overhead is acceptable. 
  858. XThis extends the usefulness and life of today's programs and data.
  859. X
  860. XTo maximize interconnectivity, the standard file structure and the 
  861. Xspecific object formats must all be general and extensible. Think 
  862. Xahead when designing an object. It should serve many purposes and 
  863. Xallow many programs to store and read back all the information they 
  864. Xneed; even squeeze in custom data. Then a programmer can store the 
  865. Xavailable data and is encouraged to include fixed contextual details. 
  866. XRecipient programs can read the needed parts, skip unrecognized stuff, 
  867. Xdefault missing data, and use the stored context to help transform 
  868. Xthe data as needed.
  869. X
  870. XScope
  871. X
  872. XIFF addresses these needs by defining a standard file structure, some 
  873. Xinitial data object types, ways to define new types, and rules for 
  874. Xaccessing these files. We can accomplish a great deal by writing programs 
  875. Xaccording to this standard, but don't expect direct compatibility 
  876. Xwith existing software. We'll need conversion programs to bridge the 
  877. Xgap from the old world.
  878. X
  879. XIFF is geared for computers that readily process information in 8-bit 
  880. Xbytes. It assumes a "physical layer" of data storage and transmission 
  881. Xthat reliably maintains "files" as strings of 8-bit bytes. The standard 
  882. Xtreats a "file" as a container of data bytes and is independent of 
  883. Xhow to find a file and whether it has a byte count.
  884. X
  885. XThis standard does not by itself implement a clipboard for cutting 
  886. Xand pasting data between programs. A clipboard needs software to mediate 
  887. Xaccess, to maintain a "contents version number" so programs can detect 
  888. Xupdates, and to manage the data in "virtual memory".
  889. X
  890. XData Abstraction
  891. X
  892. XThe basic problem is how to represent information  in a way that's 
  893. Xprogram-independent, compiler- independent, machine-independent, and 
  894. Xdevice-independent.
  895. X
  896. XThe computer science approach is "data abstraction", also known as 
  897. X"objects", "actors", and "abstract data types". A data abstraction 
  898. Xhas a "concrete representation" (its storage format), an "abstract 
  899. Xrepresentation" (its capabilities and uses), and access procedures 
  900. Xthat isolate all the calling software from the concrete representation. 
  901. XOnly the access procedures touch the data storage. Hiding mutable 
  902. Xdetails behind an interface is called "information hiding". What data 
  903. Xabstraction does is abstract from details of implementing the object, 
  904. Xnamely the selected storage representation and algorithms for manipulating 
  905. Xit.
  906. X
  907. XThe power of this approach is modularity. By adjusting the access 
  908. Xprocedures we can extend and restructure the data without impacting 
  909. Xthe interface or its callers. Conversely, we can extend and restructure 
  910. Xthe interface and callers without making existing data obsolete. It's 
  911. Xgreat for interchange!
  912. X
  913. XBut we seem to need the opposite: fixed file formats for all programs 
  914. Xto access. Actually, we could file data abstractions ("filed objects") 
  915. Xby storing the data and access procedures together. We'd have to encode 
  916. Xthe access procedures in a standard machine-independent programming 
  917. Xlanguage   la PostScript. Even still, the interface can't evolve freely 
  918. Xsince we can't update all copies of the access procedures. So we'll 
  919. Xhave to design our abstract representations for limited evolution 
  920. Xand occasional revolution (conversion).
  921. X
  922. XIn any case, today's microcomputers can't practically store data abstractions. 
  923. XThey can do the next best thing: store arbitrary types of data in 
  924. X"data chunks", each with a type identifier and a length count. The 
  925. Xtype identifier is a reference by name to the access procedures (any 
  926. Xlocal implementation). The length count enables storage-level object 
  927. Xoperations like "copy" and "skip to next" independent of object type.
  928. X
  929. XChunk writing is straightforward. Chunk reading requires a trivial 
  930. Xparser to scan each chunk and dispatch to the proper access/conversion 
  931. Xprocedure. Reading chunks nested inside other chunks requires recursion, 
  932. Xbut no lookahead or backup.
  933. X
  934. XThat's the main idea of IFF. There are, of course, a few other detailsI
  935. X
  936. XPrevious Work
  937. X
  938. XWhere our needs are similar, we borrow from existing standards.
  939. X
  940. XOur basic need to move data between independently developed programs 
  941. Xis similar to that addressed by the Apple Macintosh desk scrap or 
  942. X"clipboard" [Inside Macintosh chapter "Scrap Manager"]. The Scrap 
  943. XManager works closely with the Resource Manager, a handy filer and 
  944. Xswapper for data objects (text strings, dialog window templates, pictures, 
  945. XfontsI) including types yet to be designed [Inside Macintosh chapter 
  946. X"Resource Manager"]. The Resource Manager is a kin to Smalltalk's 
  947. Xobject swapper.
  948. X
  949. XWe will probably write a Macintosh desk accessory that converts IFF 
  950. Xfiles to and from the Macintosh clipboard for quick and easy interchange 
  951. Xwith programs like MacPaint and Resource Mover.
  952. X
  953. XMacintosh uses a simple and elegant scheme of 4-character "identifiers" 
  954. Xto identify resource types, clipboard format types, file types, and 
  955. Xfile creator programs. Alternatives are unique ID numbers assigned 
  956. Xby a central authority or by hierarchical authorities, unique ID numbers 
  957. Xgenerated by algorithm, other fixed length character strings, and 
  958. Xvariable length strings. Character string identifiers double as readable 
  959. Xsignposts in data files and programs. The choice of 4 characters is 
  960. Xa good tradeoff between storage space, fetch/compare/store time, and 
  961. Xname space size. We'll honor Apple's designers by adopting this scheme.
  962. X
  963. X"PICT" is a good example of a standard structured graphics format 
  964. X(including raster images) and its many uses [Inside Macintosh chapter 
  965. X"QuickDraw"]. Macintosh provides QuickDraw routines in ROM to create, 
  966. Xmanipulate, and display PICTs. Any application can create a PICT by 
  967. Xsimply asking QuickDraw to record a sequence of drawing commands. 
  968. XSince it's just as easy to ask QuickDraw to render a PICT to a screen 
  969. Xor a printer, it's very effective to pass them between programs, say 
  970. Xfrom an illustrator to a word processor. An important feature is the 
  971. Xability to store "comments" in a PICT which QuickDraw will ignore. 
  972. XActually, it passes them to your optional custom "comment handler".
  973. X
  974. XPostScript, Adobe's print file standard, is a more general way to 
  975. Xrepresent any print image (which is a specification for putting marks 
  976. Xon paper) [PostScript Language Manual]. In fact, PostScript is a full-fledged 
  977. Xprogramming language. To interpret a PostScript program is to render 
  978. Xa document on a raster output device. The language is defined in layers: 
  979. Xa lexical layer of identifiers, constants, and operators; a layer 
  980. Xof reverse polish semantics including scope rules and a way to define 
  981. Xnew subroutines; and a printing-specific layer of built-in identifiers 
  982. Xand operators for rendering graphic images. It is clearly a powerful 
  983. X(Turing equivalent) image definition language. PICT and a subset of 
  984. XPostScript are candidates for structured graphics standards.
  985. X
  986. XA PostScript document can be printed on any raster output device (including 
  987. Xa display) but cannot generally be edited. That's because the original 
  988. Xflexibility and constraints have been discarded. Besides, a PostScript 
  989. Xprogram may use arbitrary computation to supply parameters like placement 
  990. Xand size to each operator. A QuickDraw PICT, in comparison, is a more 
  991. Xrestricted format of graphic primitives parameterized by constants. 
  992. XSo a PICT can be edited at the level of the primitives, e.g. move 
  993. Xor thicken a line. It cannot be edited at the higher level of, say, 
  994. Xthe bar chart data which generated the picture.
  995. X
  996. XPostScript has another limitation: Not all kinds of data amount to 
  997. Xmarks on paper. A musical instrument description is one example. PostScript 
  998. Xis just not geared for such uses.
  999. X
  1000. X"DIF" is another example of data being stored in a general format 
  1001. Xusable by future programs [DIF Technical Specification]. DIF is a 
  1002. Xformat for spreadsheet data interchange. DIF and PostScript are both 
  1003. Xexpressed in plain ASCII text files. This is very handy for printing, 
  1004. Xdebugging, experimenting, and transmitting across modems. It can have 
  1005. Xsubstantial cost in compaction and read/write work, depending on use. 
  1006. XWe won't store IFF files this way but we could define an ASCII alternate 
  1007. Xrepresentation with a converter program.
  1008. X
  1009. XInterScript is Xerox' standard for interchange of editable documents 
  1010. X[Introduction to InterScript]. It approaches a harder problem: How 
  1011. Xto represent editable word processor documents that may contain formatted 
  1012. Xtext, pictures, cross-references like figure numbers, and even highly 
  1013. Xspecialized objects like mathematical equations? InterScript aims 
  1014. Xto define one standard representation for each kind of information. 
  1015. XEach InterScript-compatible editor is supposed to preserve the objects 
  1016. Xit doesn't understand and even maintain nested cross-references. So 
  1017. Xa simple word processor would let you edit the text of a fancy document 
  1018. Xwithout discarding the equations or disrupting the equation numbers.
  1019. X
  1020. XOur task is similarly to store high level information and preserve 
  1021. Xas much content as practical while moving it between programs. But 
  1022. Xwe need to span a larger universe of data types and cannot expect 
  1023. Xto centrally define them all. Fortunately, we don't need to make programs 
  1024. Xpreserve information that they don't understand. And for better or 
  1025. Xworse, we don't have to tackle general-purpose cross-references yet.
  1026. X
  1027. X
  1028. X
  1029. X3. Primitive Data Types
  1030. X
  1031. XAtomic components such as integers and characters that are interpretable 
  1032. Xdirectly by the CPU are specified in one format for all processors. 
  1033. XWe chose a format that's most convenient for the Motorola MC68000 
  1034. Xprocessor [M68000 16/32-Bit Microprocessor Programmer's Reference 
  1035. XManual].
  1036. X
  1037. XN.B.: Part 3 dictates the format for "primitive" data types where and 
  1038. Xonly where used in the overall file structure and standard kinds of 
  1039. Xchunks (Cf. Chunks). The number of such occurrences will be small 
  1040. Xenough that the costs of conversion, storage, and management of processor-
  1041. Xspecific files would far exceed the costs of conversion during I/O by "foreign" 
  1042. Xprograms. A particular data chunk may be specified with a different 
  1043. Xformat for its internal primitive types or with processor- or environment-
  1044. Xspeci fic variants if necessary to optimize local usage. Since that hurts 
  1045. Xdata interchange, it's not recommended. (Cf. Designing New Data Sections, 
  1046. Xin Part 4.)
  1047. X
  1048. XAlignment
  1049. X
  1050. XAll data objects larger than a byte are aligned on even byte addresses 
  1051. Xrelative to the start of the file. This may require padding. Pad bytes 
  1052. Xare to be written as zeros, but don't count on that when reading.
  1053. X
  1054. XThis means that every odd-length "chunk" (see below) must be padded 
  1055. Xso that the next one will fall on an even boundary. Also, designers 
  1056. Xof structures to be stored in chunks should include pad fields where 
  1057. Xneeded to align every field larger than a byte. Zeros should be stored 
  1058. Xin all the pad bytes.
  1059. X
  1060. XJustification: Even-alignment causes a little extra work for files 
  1061. Xthat are used only on certain processors but allows 68000 programs 
  1062. Xto construct and scan the data in memory and do block I/O. You just 
  1063. Xadd an occasional pad field to data structures that you're going to 
  1064. Xblock read/write or else stream read/write an extra byte. And the 
  1065. Xsame source code works on all processors. Unspecified alignment, on 
  1066. Xthe other hand, would force 68000 programs to (dis)assemble word and 
  1067. Xlong-word data one byte at a time. Pretty cumbersome in a high level 
  1068. Xlanguage. And if you don't conditionally compile that out for other 
  1069. Xprocessors, you won't gain anything.
  1070. X
  1071. XNumbers
  1072. X
  1073. XNumeric types supported are two's complement binary integers in the 
  1074. Xformat used by the MC68000 processor high byte first, high word first the 
  1075. Xreverse of 8088 and 6502 format. They could potentially include signed 
  1076. Xand unsigned 8, 16, and 32 bit integers but the standard only uses 
  1077. Xthe following:
  1078. X
  1079. XUBYTE     8 bits unsigned
  1080. XWORD    16 bits signed
  1081. XUWORD    16 bits unsigned
  1082. XLONG    32 bits signed
  1083. X
  1084. XThe actual type definitions depend on the CPU and the compiler. In 
  1085. Xthis document, we'll express data type definitions in the C programming 
  1086. Xlanguage. [See C, A Reference Manual.] In 68000 Lattice C:
  1087. X
  1088. Xtypedef unsigned char    UBYTE;    /*  8 bits unsigned    */
  1089. Xtypedef short    WORD;    /* 16 bits signed    */
  1090. Xtypedef unsigned short    UWORD;    /* 16 bits unsigned    */
  1091. Xtypedef long    LONG;    /* 32 bits signed    */
  1092. X
  1093. XCharacters
  1094. X
  1095. XThe following character set is assumed wherever characters are used, 
  1096. Xe.g. in text strings, IDs, and TEXT chunks (see below).
  1097. X
  1098. XCharacters are encoded in 8-bit ASCII. Characters in the range NUL 
  1099. X(hex 0) through DEL (hex 7F) are well defined by the 7-bit ASCII standard. 
  1100. XIFF uses the graphic group RJS (SP, hex 20) through R~S (hex 7E).
  1101. X
  1102. XMost of the control character group hex 01 through hex 1F have no 
  1103. Xstandard meaning in IFF. The control character LF (hex 0A) is defined 
  1104. Xas a "newline" character. It denotes an intentional line break, that 
  1105. Xis, a paragraph or line terminator. (There is no way to store an automatic 
  1106. Xline break. That is strictly a function of the margins in the environment 
  1107. Xthe text is placed.) The control character ESC (hex 1B) is a reserved 
  1108. Xescape character under the rules of ANSI standard 3.64-1979 American 
  1109. XNational Standard Additional Control Codes for Use with ASCII, ISO 
  1110. Xstandard 2022, and ISO/DIS standard 6429.2.
  1111. X
  1112. XCharacters in the range hex 7F through hex FF are not globally defined 
  1113. Xin IFF. They are best left reserved for future standardization. But 
  1114. Xnote that the FORM type FTXT (formatted text) defines the meaning 
  1115. Xof these characters within FTXT forms. In particular, character values 
  1116. Xhex 7F through hex 9F are control codes while characters hex A0 through 
  1117. Xhex FF are extended graphic characters like  , as per the ISO and 
  1118. XANSI standards cited above. [See the supplementary document "FTXT" 
  1119. XIFF Formatted Text.]
  1120. X
  1121. XDates
  1122. X
  1123. XA "creation date" is defined as the date and time a stream of data 
  1124. Xbytes was created. (Some systems call this a "last modified date".) 
  1125. XEditing some data changes its creation date. Moving the data between 
  1126. Xvolumes or machines does not.
  1127. X
  1128. XThe IFF standard date format will be one of those used in MS-DOS, 
  1129. XMacintosh, or Amiga DOS (probably a 32-bit unsigned number of seconds 
  1130. Xsince a reference point). Issue: Investigate these three.
  1131. X
  1132. XType IDs
  1133. X
  1134. XA "type ID", "property name", "FORM type", or any other IFF identifier 
  1135. Xis a 32-bit value: the concatenation of four ASCII characters in the 
  1136. Xrange R S (SP, hex 20) through R~S (hex 7E). Spaces (hex 20) should 
  1137. Xnot precede printing characters; trailing spaces are ok. Control characters 
  1138. Xare forbidden.
  1139. X
  1140. Xtypedef CHAR ID[4];
  1141. X
  1142. XIDs are compared using a simple 32-bit case-dependent equality test.
  1143. X
  1144. XData section type IDs (aka FORM types) are restriced IDs. (Cf. Data 
  1145. XSections.) Since they may be stored in filename extensions (Cf. Single 
  1146. XPurpose Files) lower case letters and punctuation marks are forbidden. 
  1147. XTrailing spaces are ok.
  1148. X
  1149. XCarefully choose those four characters when you pick a new ID. Make 
  1150. Xthem mnemonic so programmers can look at an interchange format file 
  1151. Xand figure out what kind of data it contains. The name space makes 
  1152. Xit possible for developers scattered around the globe to generate 
  1153. XID values with minimal collisions so long as they choose specific 
  1154. Xnames like "MUS4" instead of general ones like "TYPE" and "FILE". 
  1155. XEA will "register" new FORM type IDs and format descriptions as they're 
  1156. Xdevised, but collisions will be improbable so there will be no pressure 
  1157. Xon this "clearinghouse" process. Appendix A has a list of currently 
  1158. Xdefined IDs.
  1159. X
  1160. XSometimes it's necessary to make data format changes that aren't backward 
  1161. Xcompatible. Since IDs are used to denote data formats in IFF, new 
  1162. XIDs are chosen to denote revised formats. Since programs won't read 
  1163. Xchunks whose IDs they don't recognize (see Chunks, below), the new 
  1164. XIDs keep old programs from stumbling over new data. The conventional 
  1165. Xway to chose a "revision" ID is to increment the last character if 
  1166. Xit's a digit or else change the last character to a digit. E.g. first 
  1167. Xand second revisions of the ID "XY" would be "XY1" and "XY2". Revisions 
  1168. Xof "CMAP" would be "CMA1" and "CMA2".
  1169. X
  1170. XChunks
  1171. X
  1172. XChunks are the building blocks in the IFF structure. The form expressed 
  1173. Xas a C typedef is:
  1174. X
  1175. Xtypedef struct {
  1176. X    ID    ckID;
  1177. X    LONG    ckSize;    /* sizeof(ckData) */
  1178. X    UBYTE    ckData[/* ckSize */];
  1179. X    } Chunk;
  1180. X
  1181. XWe can diagram an example chunk a "CMAP" chunk containing 12 data 
  1182. Xbytes like this:
  1183. X            ----------------
  1184. X        ckID:    |    'CMAP'    |
  1185. X        ckSize: |      12      |
  1186. X        ckData: | 0, 0, 0, 32  |   -------- 
  1187. X            | 0, 0, 64, 0  |    12 bytes
  1188. X            | 0, 0, 64, 0  |   ---------
  1189. X            ----------------
  1190. X
  1191. XThe fixed header part means "Here's a type ckID chunk with ckSize 
  1192. Xbytes of data."
  1193. X
  1194. XThe ckID identifies the format and purpose of the chunk. As a rule, 
  1195. Xa program must recognize ckID to interpret ckData. It should skip 
  1196. Xover all unrecognized chunks. The ckID also serves as a format version 
  1197. Xnumber as long as we pick new IDs to identify new formats of ckData 
  1198. X(see above).
  1199. X
  1200. XThe following ckIDs are universally reserved to identify chunks with 
  1201. Xparticular IFF meanings: "LIST", "FORM", "PROP", "CAT ", and "    
  1202. X". The special ID "    " (4 spaces) is a ckID for "filler" chunks, 
  1203. Xthat is, chunks that fill space but have no meaningful contents. The 
  1204. XIDs "LIS1" through "LIS9", "FOR1" through "FOR9", and "CAT1" through 
  1205. X"CAT9" are reserved for future "version number" variations. All IFF-compatible 
  1206. Xsoftware must account for these 23 chunk IDs. Appendix A has a list 
  1207. Xof predefined IDs.
  1208. X
  1209. XThe ckSize is a logical block size how many data bytes are in ckData. 
  1210. XIf ckData is an odd number of bytes long, a 0 pad byte follows which 
  1211. Xis not included in ckSize. (Cf. Alignment.) A chunk's total physical 
  1212. Xsize is ckSize rounded up to an even number plus the size of the header. 
  1213. XSo the smallest chunk is 8 bytes long with ckSize = 0. For the sake 
  1214. Xof following chunks, programs must respect every chunk's ckSize as 
  1215. Xa virtual end-of-file for reading its ckData even if that data is 
  1216. Xmalformed, e.g. if nested contents are truncated.
  1217. X
  1218. XWe can describe the syntax of a chunk as a regular expression with 
  1219. X"#" representing the ckSize, i.e. the length of the following {braced} 
  1220. Xbytes. The "[0]" represents a sometimes needed pad byte. (The regular 
  1221. Xexpressions in this document are collected in Appendix A along with 
  1222. Xan explanation of notation.)
  1223. X
  1224. XChunk    ::= ID #{ UBYTE* } [0]
  1225. X
  1226. XOne chunk output technique is to stream write a chunk header, stream 
  1227. Xwrite the chunk contents, then random access back to the header to 
  1228. Xfill in the size. Another technique is to make a preliminary pass 
  1229. Xover the data to compute the size, then write it out all at once.
  1230. X
  1231. XStrings, String Chunks, and String Properties
  1232. X
  1233. XIn a string of ASCII text, LF denotes a forced line break (paragraph 
  1234. Xor line terminator). Other control characters are not used. (Cf. Characters.)
  1235. X
  1236. XThe ckID for a chunk that contains a string of plain, unformatted 
  1237. Xtext is "TEXT". As a practical matter, a text string should probably 
  1238. Xnot be longer than 32767 bytes. The standard allows up to 231 - 1 
  1239. Xbytes.
  1240. X
  1241. XWhen used as a data property (see below), a text string chunk may 
  1242. Xbe 0 to 255 characters long. Such a string is readily converted to 
  1243. Xa C string or a Pascal STRING[255]. The ckID of a property must be 
  1244. Xthe property name, not "TEXT".
  1245. X
  1246. XWhen used as a part of a chunk or data property, restricted C string 
  1247. Xformat is normally used. That means 0 to 255 characters followed by 
  1248. Xa NUL byte (ASCII value 0).
  1249. X
  1250. XData Properties
  1251. X
  1252. XData properties specify attributes for following (non-property) chunks. 
  1253. XA data property essentially says "identifier = value", for example 
  1254. X"XY = (10, 200)", telling something about following chunks. Properties 
  1255. Xmay only appear inside data sections ("FORM" chunks, cf. Data Sections) 
  1256. Xand property sections ("PROP" chunks, cf. Group PROP).
  1257. X
  1258. XThe form of a data property is a special case of Chunk. The ckID is 
  1259. Xa property name as well as a property type. The ckSize should be small 
  1260. Xsince data properties are intended to be accumulated in RAM when reading 
  1261. Xa file. (256 bytes is a reasonable upper bound.) Syntactically:
  1262. X
  1263. XProperty    ::= Chunk
  1264. X
  1265. XWhen designing a data object, use properties to describe context information 
  1266. Xlike the size of an image, even if they don't vary in your program. 
  1267. XOther programs will need this information.
  1268. X
  1269. XThink of property settings as assignments to variables in a programming 
  1270. Xlanguage. Multiple assignments are redundant and local assignments 
  1271. Xtemporarily override global assignments. The order of assignments 
  1272. Xdoesn't matter as long as they precede the affected chunks. (Cf. LISTs, 
  1273. XCATs, and Shared Properties.)
  1274. X
  1275. XEach object type (FORM type) is a local name space for property IDs. 
  1276. XThink of a "CMAP" property in a "FORM ILBM" as the qualified ID "ILBM.CMAP". 
  1277. XProperty IDs specified when an object type is designed (and therefore 
  1278. Xknown to all clients) are called "standard" while specialized ones 
  1279. Xadded later are "nonstandard".
  1280. X
  1281. XLinks
  1282. X
  1283. XIssue: A standard mechanism for "links" or "cross references" is very 
  1284. Xdesirable for things like combining images and sounds into animations. 
  1285. XPerhaps we'll define "link" chunks within FORMs that refer to other 
  1286. XFORMs or to specific chunks within the same and other FORMs. This 
  1287. Xneeds further work. EA IFF 1985 has no standard link mechanism.
  1288. X
  1289. XFor now, it may suffice to read a list of, say, musical instruments, 
  1290. Xand then just refer to them within a musical score by index number.
  1291. X
  1292. XFile References
  1293. X
  1294. XIssue: We may need a standard form for references to other files. 
  1295. XA "file ref" could name a directory and a file in the same type of 
  1296. Xoperating system as the ref's originator. Following the reference 
  1297. Xwould expect the file to be on some mounted volume. In a network environment, 
  1298. Xa file ref could name a server, too.
  1299. X
  1300. XIssue: How can we express operating-system independent file refs?
  1301. X
  1302. XIssue: What about a means to reference a portion of another file? 
  1303. XWould this be a "file ref" plus a reference to a "link" within the 
  1304. Xtarget file?
  1305. X
  1306. X
  1307. X
  1308. X4. Data Sections
  1309. X
  1310. XThe first thing we need of a file is to check: Does it contain IFF 
  1311. Xdata and, if so, does it contain the kind of data we're looking for? 
  1312. XSo we come to the notion of a "data section".
  1313. X
  1314. XA "data section" or IFF "FORM" is one self-contained "data object" 
  1315. Xthat might be stored in a file by itself. It is one high level data 
  1316. Xobject such as a picture or a sound effect. The IFF structure "FORM" 
  1317. Xmakes it self- identifying. It could be a composite object like a 
  1318. Xmusical score with nested musical instrument descriptions.
  1319. X
  1320. XGroup FORM
  1321. X
  1322. XA data section is a chunk with ckID "FORM" and this arrangement:
  1323. X
  1324. XFORM    ::= "FORM" #{ FormType (LocalChunk | FORM | LIST | CAT)* 
  1325. X}
  1326. XFormType    ::= ID
  1327. XLocalChunk    ::= Property | Chunk
  1328. X
  1329. XThe ID "FORM" is a syntactic keyword like "struct" in C. Think of 
  1330. Xa "struct ILBM" containing a field "CMAP". If you see "FORM" you'll 
  1331. Xknow to expect a FORM type ID (the structure name, "ILBM" in this 
  1332. Xexample) and a particular contents arrangement or "syntax" (local 
  1333. Xchunks, FORMs, LISTs, and CATs). (LISTs and CATs are discussed in 
  1334. Xpart 5, below.) A "FORM ILBM", in particular, might contain a local 
  1335. Xchunk "CMAP", an "ILBM.CMAP" (to use a qualified name).
  1336. X
  1337. XSo the chunk ID "FORM" indicates a data section. It implies that the 
  1338. Xchunk contains an ID and some number of nested chunks. In reading 
  1339. Xa FORM, like any other chunk, programs must respect its ckSize as 
  1340. Xa virtual end-of-file for reading its contents, even if they're truncated.
  1341. X
  1342. XThe FormType (or FORM type) is a restricted ID that may not contain 
  1343. Xlower case letters or punctuation characters. (Cf. Type IDs. Cf. Single 
  1344. XPurpose Files.)
  1345. X
  1346. XThe type-specific information in a FORM is composed of its "local 
  1347. Xchunks": data properties and other chunks. Each FORM type is a local 
  1348. Xname space for local chunk IDs. So "CMAP" local chunks in other FORM 
  1349. Xtypes may be unrelated to "ILBM.CMAP". More than that, each FORM type 
  1350. Xdefines semantic scope. If you know what a FORM ILBM is, you'll know 
  1351. Xwhat an ILBM.CMAP is.
  1352. X
  1353. XLocal chunks defined when the FORM type is designed (and therefore 
  1354. Xknown to all clients of this type) are called "standard" while specialized 
  1355. Xones added later are "nonstandard".
  1356. X
  1357. XAmong the local chunks, property chunks give settings for various 
  1358. Xdetails like text font while the other chunks supply the essential 
  1359. Xinformation. This distinction is not clear cut. A property setting 
  1360. Xcancelled by a later setting of the same property has effect only 
  1361. Xon data chunks in between. E.g. in the sequence:
  1362. X
  1363. Xprop1 = x  (propN = value)*  prop1 = y
  1364. X
  1365. Xwhere the propNs are not prop1, the setting prop1 = x has no effect.
  1366. X
  1367. XThe following universal chunk IDs are reserved inside any FORM: "LIST", 
  1368. X"FORM", "PROP", "CAT ", "JJJJ", "LIS1" through "LIS9", "FOR1" through 
  1369. X"FOR9", and "CAT1" through "CAT9". (Cf. Chunks. Cf. Group LIST. Cf. 
  1370. XGroup PROP.) For clarity, these universal chunk names may not be FORM 
  1371. Xtype IDs, either.
  1372. X
  1373. XPart 5, below, talks about grouping FORMs into LISTs and CATs. They 
  1374. Xlet you group a bunch of FORMs but don't impose any particular meaning 
  1375. Xor constraints on the grouping. Read on.
  1376. X
  1377. XComposite FORMs
  1378. X
  1379. XA FORM chunk inside a FORM is a full-fledged data section. This means 
  1380. Xyou can build a composite object like a multi-frame animation sequence 
  1381. Xfrom available picture FORMs and sound effect FORMs. You can insert 
  1382. Xadditional chunks with information like frame rate and frame count.
  1383. X
  1384. XUsing composite FORMs, you leverage on existing programs that create 
  1385. Xand edit the component FORMs. Those editors may even look into your 
  1386. Xcomposite object to copy out its type of component, although it'll 
  1387. Xbe the rare program that's fancy enough to do that. Such editors are 
  1388. Xnot allowed to replace their component objects within your composite 
  1389. Xobject. That's because the IFF standard lets you specify consistency 
  1390. Xrequirements for the composite FORM such as maintaining a count or 
  1391. Xa directory of the components. Only programs that are written to uphold 
  1392. Xthe rules of your FORM type should create or modify such FORMs.
  1393. X
  1394. XTherefore, in designing a program that creates composite objects, 
  1395. Xyou are strongly requested to provide a facility for your users to 
  1396. Ximport and export the nested FORMs. Import and export could move the 
  1397. Xdata through a clipboard or a file.
  1398. X
  1399. XHere are several existing FORM types and rules for defining new ones.
  1400. X
  1401. XFTXT
  1402. X
  1403. XAn FTXT data section contains text with character formatting information 
  1404. Xlike fonts and faces. It has no paragraph or document formatting information 
  1405. Xlike margins and page headers. FORM FTXT is well matched to the text 
  1406. Xrepresentation in Amiga's Intuition environment. See the supplemental 
  1407. Xdocument "FTXT" IFF Formatted Text.
  1408. X
  1409. XILBM
  1410. X
  1411. X"ILBM" is an InterLeaved BitMap image with color map; a machine-independent 
  1412. Xformat for raster images. FORM ILBM is the standard image file format 
  1413. Xfor the Commodore-Amiga computer and is useful in other environments, 
  1414. Xtoo. See the supplemental document "ILBM" IFF Interleaved Bitmap.
  1415. X
  1416. XPICS
  1417. X
  1418. XThe data chunk inside a "PICS" data section has ID "PICT" and holds 
  1419. Xa QuickDraw picture. Issue: Allow more than one PICT in a PICS? See 
  1420. XInside Macintosh chapter "QuickDraw" for details on PICTs and how 
  1421. Xto create and display them on the Macintosh computer.
  1422. X
  1423. XThe only standard property for PICS is "XY", an optional property 
  1424. Xthat indicates the position of the PICT relative to "the big picture". 
  1425. XThe contents of an XY is a QuickDraw Point.
  1426. X
  1427. XNote: PICT may be limited to Macintosh use, in which case there'll 
  1428. Xbe another format for structured graphics in other environments.
  1429. X
  1430. XOther Macintosh Resource Types
  1431. X
  1432. XSome other Macintosh resource types could be adopted for use within 
  1433. XIFF files; perhaps MWRT, ICN, ICN#, and STR#.
  1434. X
  1435. XIssue: Consider the candidates and reserve some more IDs.
  1436. X
  1437. XDesigning New Data Sections
  1438. X
  1439. XSupplemental documents will define additional object types. A supplement 
  1440. Xneeds to specify the object's purpose, its FORM type ID, the IDs and 
  1441. Xformats of standard local chunks, and rules for generating and interpreting 
  1442. Xthe data. It's a good idea to supply typedefs and an example source 
  1443. Xprogram that accesses the new object. See "ILBM" IFF Interleaved Bitmap 
  1444. Xfor a good example.
  1445. X
  1446. XAnyone can pick a new FORM type ID but should reserve it with Electronic 
  1447. XArts at their earliest convenience. [Issue: EA contact person? Hand 
  1448. Xthis off to another organization?] While decentralized format definitions 
  1449. Xand extensions are possible in IFF, our preference is to get design 
  1450. Xconsensus by committee, implement a program to read and write it, 
  1451. Xperhaps tune the format, and then publish the format with example 
  1452. Xcode. Some organization should remain in charge of answering questions 
  1453. Xand coordinating extensions to the format.
  1454. X
  1455. XIf it becomes necessary to revise the design of some data section, 
  1456. Xits FORM type ID will serve as a version number (Cf. Type IDs). E.g. 
  1457. Xa revised "VDEO" data section could be called "VDE1". But try to get 
  1458. Xby with compatible revisions within the existing FORM type.
  1459. X
  1460. XIn a new FORM type, the rules for primitive data types and word-alignment 
  1461. X(Cf. Primitive Data Types) may be overriden for the contents of its 
  1462. Xlocal chunks but not for the chunk structure itself if your documentation 
  1463. Xspells out the deviations. If machine-specific type variants are needed, 
  1464. Xe.g. to store vast numbers of integers in reverse bit order, then 
  1465. Xoutline the conversion algorithm and indicate the variant inside each 
  1466. Xfile, perhaps via different FORM types. Needless to say, variations 
  1467. Xshould be minimized.
  1468. X
  1469. XIn designing a FORM type, encapsulate all the data that other programs 
  1470. Xwill need to interpret your files. E.g. a raster graphics image should 
  1471. Xspecify the image size even if your program always uses 320 x 200 
  1472. Xpixels x 3 bitplanes. Receiving programs are then empowered to append 
  1473. Xor clip the image rectangle, to add or drop bitplanes, etc. This enables 
  1474. Xa lot more compatibility.
  1475. X
  1476. XSeparate the central data (like musical notes) from more specialized 
  1477. Xinformation (like note beams) so simpler programs can extract the 
  1478. Xcentral parts during read-in. Leave room for expansion so other programs 
  1479. Xcan squeeze in new kinds of information (like lyrics). And remember 
  1480. Xto keep the property chunks manageably short let's say 2 256 bytes.
  1481. X
  1482. XWhen designing a data object, try to strike a good tradeoff between 
  1483. Xa super-general format and a highly-specialized one. Fit the details 
  1484. Xto at least one particular need, for example a raster image might 
  1485. Xas well store pixels in the current machine's scan order. But add 
  1486. Xthe kind of generality that makes it usable with foreseeable hardware 
  1487. Xand software. E.g. use a whole byte for each red, green, and blue 
  1488. Xcolor value even if this year's computer has only 4-bit video DACs. 
  1489. XThink ahead and help other programs so long as the overhead is acceptable. 
  1490. XE.g. run compress a raster by scan line rather than as a unit so future 
  1491. Xprograms can swap images by scan line to and from secondary storage.
  1492. X
  1493. XTry to design a general purpose "least common multiple" format that 
  1494. Xencompasses the needs of many programs without getting too complicated. 
  1495. XLet's coalesce our uses around a few such formats widely separated 
  1496. Xin the vast design space. Two factors make this flexibility and simplicity 
  1497. Xpractical. First, file storage space is getting very plentiful, so 
  1498. Xcompaction is not a priority. Second, nearly any locally-performed 
  1499. Xdata conversion work during file reading and writing will be cheap 
  1500. Xcompared to the I/O time.
  1501. X
  1502. XIt must be ok to copy a LIST or FORM or CAT intact, e.g. to incorporate 
  1503. Xit into a composite FORM. So any kind of internal references within 
  1504. Xa FORM must be relative references. They could be relative to the 
  1505. Xstart of the containing FORM, relative from the referencing chunk, 
  1506. Xor a sequence number into a collection.
  1507. X
  1508. XWith composite FORMs, you leverage on existing programs that create 
  1509. Xand edit the components. If you write a program that creates composite 
  1510. Xobjects, please provide a facility for your users to import and export 
  1511. Xthe nested FORMs. The import and export functions may move data through 
  1512. Xa separate file or a clipboard.
  1513. X
  1514. XFinally, don't forget to specify all implied rules in detail.
  1515. X
  1516. X
  1517. X
  1518. X5. LISTs, CATs, and Shared Properties
  1519. X
  1520. XData often needs to be grouped together like a list of icons. Sometimes 
  1521. Xa trick like arranging little images into a big raster works, but 
  1522. Xgenerally they'll need to be structured as a first class group. The 
  1523. Xobjects "LIST" and "CAT" are IFF-universal mechanisms for this purpose.
  1524. X
  1525. XProperty settings sometimes need to be shared over a list of similar 
  1526. Xobjects. E.g. a list of icons may share one color map. LIST provides 
  1527. Xa means called "PROP" to do this. One purpose of a LIST is to define 
  1528. Xthe scope of a PROP. A "CAT", on the other hand, is simply a concatenation 
  1529. Xof objects.
  1530. X
  1531. XSimpler programs may skip LISTs and PROPs altogether and just handle 
  1532. XFORMs and CATs. All "fully-conforming" IFF programs also know about 
  1533. X"CAT ", "LIST", and "PROP". Any program that reads a FORM inside a 
  1534. XLIST must process shared PROPs to correctly interpret that FORM.
  1535. X
  1536. XGroup CAT
  1537. X
  1538. XA CAT is just an untyped group of data objects.
  1539. X
  1540. XStructurally, a CAT is a chunk with chunk ID "CAT " containing a "contents 
  1541. Xtype" ID followed by the nested objects. The ckSize of each contained 
  1542. Xchunk is essentially a relative pointer to the next one.
  1543. X
  1544. XCAT    ::= "CAT " #{ ContentsType (FORM | LIST | CAT)* }
  1545. XContentsType    ::= ID    -- a hint or an "abstract data type" ID
  1546. X
  1547. XIn reading a CAT, like any other chunk, programs must respect it's 
  1548. XckSize as a virtual end-of-file for reading the nested objects even 
  1549. Xif they're malformed or truncated.
  1550. X
  1551. XThe "contents type" following the CAT's ckSize indicates what kind 
  1552. Xof FORMs are inside. So a CAT of ILBMs would store "ILBM" there. It's 
  1553. Xjust a hint. It may be used to store an "abstract data type". A CAT 
  1554. Xcould just have blank contents ID ("JJJJ") if it contains more than 
  1555. Xone kind of FORM.
  1556. X
  1557. XCAT defines only the format of the group. The group's meaning is open 
  1558. Xto interpretation. This is like a list in LISP: the structure of cells 
  1559. Xis predefined but the meaning of the contents as, say, an association 
  1560. Xlist depends on use. If you need a group with an enforced meaning 
  1561. X(an "abstract data type" or Smalltalk "subclass"), some consistency 
  1562. Xconstraints, or additional data chunks, use a composite FORM instead 
  1563. X(Cf. Composite FORMs).
  1564. X
  1565. XSince a CAT just means a concatenation of objects, CATs are rarely 
  1566. Xnested. Programs should really merge CATs rather than nest them.
  1567. X
  1568. XGroup LIST
  1569. X
  1570. XA LIST defines a group very much like CAT but it also gives a scope 
  1571. Xfor PROPs (see below). And unlike CATs, LISTs should not be merged 
  1572. Xwithout understanding their contents.
  1573. X
  1574. XStructurally, a LIST is a chunk with ckID "LIST" containing a "contents 
  1575. Xtype" ID, optional shared properties, and the nested contents (FORMs, 
  1576. XLISTs, and CATs), in that order. The ckSize of each contained chunk 
  1577. Xis a relative pointer to the next one. A LIST is not an arbitrary 
  1578. Xlinked list the cells are simply concatenated.
  1579. X
  1580. XLIST    ::= "LIST" #{ ContentsType PROP* (FORM | LIST | CAT)* }
  1581. XContentsType    ::= ID
  1582. X
  1583. XGroup PROP
  1584. X
  1585. XPROP chunks may appear in LISTs (not in FORMs or CATs). They supply 
  1586. Xshared properties for the FORMs in that LIST. This ability to elevate 
  1587. Xsome property settings to shared status for a list of forms is useful 
  1588. Xfor both indirection and compaction. E.g. a list of images with the 
  1589. Xsame size and colors can share one "size" property and one "color 
  1590. Xmap" property. Individual FORMs can override the shared settings.
  1591. X
  1592. XThe contents of a PROP is like a FORM with no data chunks:
  1593. X
  1594. XPROP    ::= "PROP" #{ FormType Property* }
  1595. X
  1596. XIt means, "Here are the shared properties for FORM type <<FormType>."
  1597. X
  1598. XA LIST may have at most one PROP of a FORM type, and all the PROPs 
  1599. Xmust appear before any of the FORMs or nested LISTs and CATs. You 
  1600. Xcan have subsequences of FORMs sharing properties by making each subsequence 
  1601. Xa LIST.
  1602. X
  1603. XScoping: Think of property settings as variable bindings in nested 
  1604. Xblocks of a programming language. Where in C you could write:
  1605. X
  1606. XTEXT_FONT text_font = Courier;    /* program's global default    */
  1607. X
  1608. XFile(); {
  1609. X    TEXT_FONT text_font = TimesRoman;    /* shared setting    */
  1610. X
  1611. X        {
  1612. X        TEXT_FONT text_font = Helvetica;  /* local setting    */
  1613. X        Print("Hello ");    /* uses font Helvetica    */
  1614. X        }
  1615. X
  1616. X        {
  1617. X        Print("there.");    /* uses font TimesRoman    */
  1618. X        }
  1619. X    }
  1620. X
  1621. XAn IFF file could contain:
  1622. X
  1623. XLIST {
  1624. X    PROP TEXT {
  1625. X        FONT {TimesRoman}    /* shared setting    */
  1626. X        }
  1627. X
  1628. X    FORM TEXT {
  1629. X        FONT {Helvetica}    /* local setting    */
  1630. X        CHRS {Hello }        /* uses font Helvetica    */
  1631. X        }
  1632. X
  1633. X    FORM TEXT {
  1634. X        CHRS {there.}    /* uses font TimesRoman    */
  1635. X        }
  1636. X    }
  1637. X
  1638. XThe shared property assignments selectively override the reader's 
  1639. Xglobal defaults, but only for FORMs within the group. A FORM's own 
  1640. Xproperty assignments selectively override the global and group-supplied 
  1641. Xvalues. So when reading an IFF file, keep property settings on a stack. 
  1642. XThey're designed to be small enough to hold in main memory.
  1643. X
  1644. XShared properties are semantically equivalent to copying those properties 
  1645. Xinto each of the nested FORMs right after their FORM type IDs.
  1646. X
  1647. XProperties for LIST
  1648. X
  1649. XOptional "properties for LIST" store the origin of the list's contents 
  1650. Xin a PROP chunk for the fake FORM type "LIST". They are the properties 
  1651. Xoriginating program "OPGM", processor family "OCPU", computer type 
  1652. X"OCMP", computer serial number or network address "OSN ", and user 
  1653. Xname "UNAM". In our imperfect world, these could be called upon to 
  1654. Xdistinguish between unintended variations of a data format or to work 
  1655. Xaround bugs in particular originating/receiving program pairs. Issue: 
  1656. XSpecify the format of these properties.
  1657. X
  1658. XA creation date could also be stored in a property but let's ask that 
  1659. Xfile creating, editing, and transporting programs maintain the correct 
  1660. Xdate in the local file system. Programs that move files between machine 
  1661. Xtypes are expected to copy across the creation dates.
  1662. X
  1663. X
  1664. X
  1665. X6. Standard File Structure
  1666. X
  1667. XFile Structure Overview
  1668. X
  1669. XAn IFF file is just a single chunk of type FORM, LIST, or CAT. Therefore 
  1670. Xan IFF file can be recognized by its first 4 bytes: "FORM", "LIST", 
  1671. Xor "CAT ". Any file contents after the chunk's end are to be ignored.
  1672. X
  1673. XSince an IFF file can be a group of objects, programs that read/write 
  1674. Xsingle objects can communicate to an extent with programs that read/write 
  1675. Xgroups. You're encouraged to write programs that handle all the objects 
  1676. Xin a LIST or CAT. A graphics editor, for example, could process a 
  1677. Xlist of pictures as a multiple page document, one page at a time.
  1678. X
  1679. XPrograms should enforce IFF's syntactic rules when reading and writing 
  1680. Xfiles. This ensures robust data transfer. The public domain IFF reader/writer 
  1681. Xsubroutine package does this for you. A utility program "IFFCheck" 
  1682. Xis available that scans an IFF file and checks it for conformance 
  1683. Xto IFF's syntactic rules. IFFCheck also prints an outline of the chunks 
  1684. Xin the file, showing the ckID and ckSize of each. This is quite handy 
  1685. Xwhen building IFF programs. Example programs are also available to 
  1686. Xshow details of reading and writing IFF files.
  1687. X
  1688. XA merge program "IFFJoin" will be available that logically appends 
  1689. XIFF files into a single CAT group. It "unwraps" each input file that 
  1690. Xis a CAT so that the combined file isn't nested CATs.
  1691. X
  1692. XIf we need to revise the IFF standard, the three anchoring IDs will 
  1693. Xbe used as "version numbers". That's why IDs "FOR1" through "FOR9", 
  1694. X"LIS1" through "LIS9", and "CAT1" through "CAT9" are reserved.
  1695. X
  1696. XIFF formats are designed for reasonable performance with floppy disks. 
  1697. XWe achieve considerable simplicity in the formats and programs by 
  1698. Xrelying on the host file system rather than defining universal grouping 
  1699. Xstructures like directories for LIST contents. On huge storage systems, 
  1700. XIFF files could be leaf nodes in a file structure like a B-tree. Let's 
  1701. Xhope the host file system implements that for us!
  1702. X
  1703. XThre are two kinds of IFF files: single purpose files and scrap files. 
  1704. XThey differ in the interpretation of multiple data objects and in 
  1705. Xthe file's external type.
  1706. X
  1707. XSingle Purpose Files
  1708. X
  1709. XA single purpose IFF file is for normal "document" and "archive" storage. 
  1710. XThis is in contrast with "scrap files" (see below) and temporary backing 
  1711. Xstorage (non-interchange files).
  1712. X
  1713. XThe external file type (or filename extension, depending on the host 
  1714. Xfile system) indicates the file's contents. It's generally the FORM 
  1715. Xtype of the data contained, hence the restrictions on FORM type IDs.
  1716. X
  1717. XProgrammers and users may pick an "intended use" type as the filename 
  1718. Xextension to make it easy to filter for the relevant files in a filename 
  1719. Xrequestor. This is actually a "subclass" or "subtype" that conveniently 
  1720. Xseparates files of the same FORM type that have different uses. Programs 
  1721. Xcannot demand conformity to its expected subtypes without overly restricting 
  1722. Xdata interchange since they cannot know about the subtypes to be used 
  1723. Xby future programs that users will want to exchange data with.
  1724. X
  1725. XIssue: How to generate 3-letter MS-DOS extensions from 4-letter FORM 
  1726. Xtype IDs?
  1727. X
  1728. XMost single purpose files will be a single FORM (perhaps a composite 
  1729. XFORM like a musical score containing nested FORMs like musical instrument 
  1730. Xdescriptions). If it's a LIST or a CAT, programs should skip over 
  1731. Xunrecognized objects to read the recognized ones or the first recognized 
  1732. Xone. Then a program that can read a single purpose file can read something 
  1733. Xout of a "scrap file", too.
  1734. X
  1735. XScrap Files
  1736. X
  1737. XA "scrap file" is for maximum interconnectivity in getting data between 
  1738. Xprograms; the core of a clipboard function. Scrap files may have type 
  1739. X"IFF " or filename extension ".IFF".
  1740. X
  1741. XA scrap file is typically a CAT containing alternate representations 
  1742. Xof the same basic information. Include as many alternatives as you 
  1743. Xcan readily generate. This redundancy improves interconnectivity in 
  1744. Xsituations where we can't make all programs read and write super-general 
  1745. Xformats. [Inside Macintosh chapter "Scrap Manager".] E.g. a graphically-
  1746. Xannotated musical score might be supplemented by a stripped down 4-voice 
  1747. Xmelody and by a text (the lyrics).
  1748. X
  1749. XThe originating program should write the alternate representations 
  1750. Xin order of "preference": most preferred (most comprehensive) type 
  1751. Xto least preferred (least comprehensive) type. A receiving program 
  1752. Xshould either use the first appearing type that it understands or 
  1753. Xsearch for its own "preferred" type.
  1754. X
  1755. XA scrap file should have at most one alternative of any type. (A LIST 
  1756. Xof same type objects is ok as one of the alternatives.) But don't 
  1757. Xcount on this when reading; ignore extra sections of a type. Then 
  1758. Xa program that reads scrap files can read something out of single 
  1759. Xpurpose files.
  1760. X
  1761. XRules for Reader Programs
  1762. X
  1763. XHere are some notes on building programs that read IFF files. If you 
  1764. Xuse the standard IFF reader module "IFFR.C", many of these rules and 
  1765. Xdetails will be automatically handled. (See "Support Software" in 
  1766. XAppendix A.) We recommend that you start from the example program 
  1767. X"ShowILBM.C". You should also read up on recursive descent parsers. 
  1768. X[See, for example, Compiler Construction, An Advanced Course.]
  1769. X
  1770. X%    The standard is very flexible so many programs can exchange 
  1771. Xdata. This implies a program has to scan the file and react to what's 
  1772. Xactually there in whatever order it appears. An IFF reader program 
  1773. Xis a parser.
  1774. X
  1775. X%    For interchange to really work, programs must be willing to 
  1776. Xdo some conversion during read-in. If the data isn't exactly what 
  1777. Xyou expect, say, the raster is smaller than those created by your 
  1778. Xprogram, then adjust it. Similarly, your program could crop a large 
  1779. Xpicture, add or drop bitplanes, and create/discard a mask plane. The 
  1780. Xprogram should give up gracefully on data that it can't convert.
  1781. X
  1782. X%    If it doesn't start with "FORM", "LIST", or "CAT ", it's not 
  1783. Xan IFF-85 file.
  1784. X
  1785. X%    For any chunk you encounter, you must recognize its type ID 
  1786. Xto understand its contents.
  1787. X
  1788. X%    For any FORM chunk you encounter, you must recognize its FORM 
  1789. Xtype ID to understand the contained "local chunks". Even if you don't 
  1790. Xrecognize the FORM type, you can still scan it for nested FORMs, LISTs, 
  1791. Xand CATs of interest.
  1792. X
  1793. X%    Don't forget to skip the pad byte after every odd-length chunk.
  1794. X
  1795. X%    Chunk types LIST, FORM, PROP, and CAT are generic groups. They 
  1796. Xalways contain a subtype ID followed by chunks.
  1797. X
  1798. X%    Readers ought to handle a CAT of FORMs in a file. You may treat 
  1799. Xthe FORMs like document pages to sequence through or just use the 
  1800. Xfirst FORM.
  1801. X
  1802. X%    Simpler IFF readers completely skip LISTs. "Fully IFF-conforming" 
  1803. Xreaders are those that handle LISTs, even if just to read the first 
  1804. XFORM from a file. If you do look into a LIST, you must process shared 
  1805. Xproperties (in PROP chunks) properly. The idea is to get the correct 
  1806. Xdata or none at all.
  1807. X
  1808. X%    The nicest readers are willing to look into unrecognized FORMs 
  1809. Xfor nested FORM types that they do recognize. For example, a musical 
  1810. Xscore may contain nested instrument descriptions and an animation 
  1811. Xfile may contain still pictures.
  1812. X
  1813. XNote to programmers: Processing PROP chunks is not simple! You'll 
  1814. Xneed some background in interpreters with stack frames. If this is 
  1815. Xforeign to you, build programs that read/write only one FORM per file. 
  1816. XFor the more intrepid programmers, the next paragraph summarizes how 
  1817. Xto process LISTs and PROPs. See the general IFF reader module "IFFR.C" 
  1818. Xand the example program "ShowILBM.C" for details.
  1819. X
  1820. XAllocate a stack frame for every LIST and FORM you encounter and initialize 
  1821. Xit by copying the stack frame of the parent LIST or FORM. At the top 
  1822. Xlevel, you'll need a stack frame initialized to your program's global 
  1823. Xdefaults. While reading each LIST or FORM, store all encountered properties 
  1824. Xinto the current stack frame. In the example ShowILBM, each stack 
  1825. Xframe has a place for a bitmap header property ILBM.BMHD and a color 
  1826. Xmap property ILBM.CMAP. When you finally get to the ILBM's BODY chunk, 
  1827. Xuse the property settings accumulated in the current stack frame.
  1828. X
  1829. XAn alternate implementation would just remember PROPs encountered, 
  1830. Xforgetting each on reaching the end of its scope (the end of the containing 
  1831. XLIST). When a FORM XXXX is encountered, scan the chunks in all remembered 
  1832. XPROPs XXXX, in order, as if they appeared before the chunks actually 
  1833. Xin the FORM XXXX. This gets trickier if you read FORMs inside of FORMs.
  1834. X
  1835. XRules for Writer Programs
  1836. X
  1837. XHere are some notes on building programs that write IFF files, which 
  1838. Xis much easier than reading them. If you use the standard IFF writer 
  1839. Xmodule "IFFW.C" (see "Support Software" in Appendix A), many of these 
  1840. Xrules and details will automatically be enforced. See the example 
  1841. Xprogram "Raw2ILBM.C".
  1842. X
  1843. X%    An IFF file is a single FORM, LIST, or CAT chunk.
  1844. X
  1845. X%    Any IFF-85 file must start with the 4 characters "FORM", "LIST", 
  1846. Xor "CAT ", followed by a LONG ckSize. There should be no data after 
  1847. Xthe chunk end.
  1848. X
  1849. X%    Chunk types LIST, FORM, PROP, and CAT are generic. They always 
  1850. Xcontain a subtype ID followed by chunks. These three IDs are universally 
  1851. Xreserved, as are "LIS1" through "LIS9", "FOR1" through "FOR9", "CAT1" 
  1852. Xthrough "CAT9", and "    ".
  1853. X
  1854. X%    Don't forget to write a 0 pad byte after each odd-length chunk.
  1855. X
  1856. X%    Four techniques for writing an IFF group: (1) build the data 
  1857. Xin a file mapped into virtual memory, (2) build the data in memory 
  1858. Xblocks and use block I/O, (3) stream write the data piecemeal and 
  1859. X(don't forget!) random access back to set the group length count, 
  1860. Xand (4) make a preliminary pass to compute the length count then stream 
  1861. Xwrite the data.
  1862. X
  1863. X%    Do not try to edit a file that you don't know how to create. 
  1864. XPrograms may look into a file and copy out nested FORMs of types that 
  1865. Xthey recognize, but don't edit and replace the nested FORMs and don't 
  1866. Xadd or remove them. That could make the containing structure inconsistent. 
  1867. XYou may write a new file containing items you copied (or copied and 
  1868. Xmodified) from another IFF file, but don't copy structural parts you 
  1869. Xdon't understand.
  1870. X
  1871. X%    You must adhere to the syntax descriptions in Appendex A. E.g. 
  1872. XPROPs may only appear inside LISTs.
  1873. X
  1874. X
  1875. X
  1876. X
  1877. XAppendix A. Reference
  1878. X
  1879. XType Definitions
  1880. X
  1881. XThe following C typedefs describe standard IFF structures. Declarations 
  1882. Xto use in practice will vary with the CPU and compiler. For example, 
  1883. X68000 Lattice C produces efficient comparison code if we define ID 
  1884. Xas a "LONG". A macro "MakeID" builds these IDs at compile time.
  1885. X
  1886. X/* Standard IFF types, expressed in 68000 Lattice C.    */
  1887. X
  1888. Xtypedef unsigned char UBYTE;    /*  8 bits unsigned    */
  1889. Xtypedef short WORD;    /* 16 bits signed    */
  1890. Xtypedef unsigned short UWORD;    /* 16 bits unsigned    */
  1891. Xtypedef long LONG;    /* 32 bits signed    */
  1892. X
  1893. Xtypedef char ID[4];    /* 4 chars in ' ' through '~'    */
  1894. X
  1895. Xtypedef struct {
  1896. X    ID    ckID;
  1897. X    LONG    ckSize;    /* sizeof(ckData)    */
  1898. X    UBYTE    ckData[/* ckSize */];
  1899. X    } Chunk;
  1900. X
  1901. X/* ID typedef and builder for 68000 Lattice C. */
  1902. Xtypedef LONG ID;     /* 4 chars in ' ' through '~'    */
  1903. X#define MakeID(a,b,c,d) ( (a)<<<<24 | (b)<<<<16 | (c)<<<<8 | (d) )
  1904. X
  1905. X/* Globally reserved IDs. */
  1906. X#define ID_FORM   MakeID('F','O','R','M')
  1907. X#define ID_LIST   MakeID('L','I','S','T')
  1908. X#define ID_PROP   MakeID('P','R','O','P')
  1909. X#define ID_CAT    MakeID('C','A','T',' ')
  1910. X#define ID_FILLER MakeID(' ',' ',' ',' ')
  1911. X
  1912. XSyntax Definitions
  1913. X
  1914. XHere's a collection of the syntax definitions in this document.
  1915. X
  1916. XChunk    ::= ID #{ UBYTE* } [0]
  1917. X
  1918. XProperty    ::= Chunk
  1919. X
  1920. XFORM    ::= "FORM" #{ FormType (LocalChunk | FORM | LIST | CAT)* 
  1921. X}
  1922. XFormType    ::= ID
  1923. XLocalChunk    ::= Property | Chunk
  1924. X
  1925. XCAT    ::= "CAT " #{ ContentsType (FORM | LIST | CAT)* }
  1926. XContentsType    ::= ID    -- a hint or an "abstract data type" ID
  1927. X
  1928. XLIST    ::= "LIST" #{ ContentsType PROP* (FORM | LIST | CAT)* }
  1929. XPROP    ::= "PROP" #{ FormType Property* }
  1930. X
  1931. XIn this extended regular expression notation, the token "#" represents 
  1932. Xa ckSize LONG count of the following {braced} data bytes. Literal 
  1933. Xitems are shown in "quotes", [square bracketed items] are optional, 
  1934. Xand "*" means 0 or more instances. A sometimes-needed pad byte is 
  1935. Xshown as "[0]".
  1936. X
  1937. XDefined Chunk IDs
  1938. X
  1939. XThis is a table of currently defined chunk IDs. We may also borrow 
  1940. Xsome Macintosh IDs and data formats.
  1941. X
  1942. XGroup chunk IDs
  1943. X    FORM, LIST, PROP, CAT.
  1944. XFuture revision group chunk IDs
  1945. X    FOR1 I FOR9, LIS1 I LIS9, CAT1 I CAT9.
  1946. XFORM type IDs
  1947. X    (The above group chunk IDs may not be used for FORM type IDs.)
  1948. X    (Lower case letters and punctuation marks are forbidden in FORM 
  1949. Xtype IDs.)
  1950. X    8SVX 8-bit sampled sound voice, ANBM animated bitmap, FNTR raster 
  1951. Xfont, FNTV vector font, FTXT formatted text, GSCR general-use musical 
  1952. Xscore, ILBM interleaved raster bitmap image, PDEF Deluxe Print page 
  1953. Xdefinition, PICS Macintosh picture, PLBM (obsolete), USCR Uhuru Sound 
  1954. XSoftware musical score, UVOX Uhuru Sound Software Macintosh voice, 
  1955. XSMUS simple musical score, VDEO Deluxe Video Construction Set video.
  1956. XData chunk IDs
  1957. X    "JJJJ", TEXT, PICT.
  1958. XPROP LIST property IDs
  1959. X    OPGM, OCPU, OCMP, OSN, UNAM.
  1960. X
  1961. X
  1962. X
  1963. XSupport Software
  1964. X
  1965. XThese public domain C source programs are available for use in building 
  1966. XIFF-compatible programs:
  1967. X
  1968. XIFF.H, IFFR.C, IFFW.C    
  1969. X
  1970. X        IFF reader and writer package. 
  1971. X        These modules handle many of the details of reliably 
  1972. X        reading and writing IFF files.
  1973. X
  1974. XIFFCheck.C    This handy utility program scans an IFF file, checks 
  1975. X        that the contents are well formed, and prints an outline 
  1976. X        of the chunks.
  1977. X
  1978. XPACKER.H, Packer.C, UnPacker.C    
  1979. X
  1980. X        Run encoder and decoder used for ILBM files.
  1981. X
  1982. XILBM.H, ILBMR.C, ILBMW.C    
  1983. X
  1984. X        Reader and writer support routines for raster image 
  1985. X        FORM ILBM. ILBMR calls IFFR and UnPacker. ILBMW calls 
  1986. X        IFFW and Packer.
  1987. X
  1988. XShowILBM.C    
  1989. X        Example caller of IFFR and ILBMR modules. This 
  1990. X        Commodore-Amiga program reads and displays a FORM ILBM.
  1991. XRaw2ILBM.C    
  1992. X        Example ILBM writer program. As a demonstration, it 
  1993. X        reads a raw raster image file and writes the image 
  1994. X        as a FORM ILBM file.
  1995. XILBM2Raw.C    
  1996. X        Example ILBM reader program.  Reads a FORM ILBM file
  1997. X        and writes it into a raw raster image.
  1998. X
  1999. XREMALLOC.H, Remalloc.c
  2000. X
  2001. X        Memory allocation routines used in these examples.
  2002. X
  2003. XINTUALL.H    generic "include almost everything" include-file
  2004. X        with the sequence of includes correctly specified.
  2005. X
  2006. XREADPICT.H, ReadPict.c    
  2007. X
  2008. X        given an ILBM file, read it into a bitmap and 
  2009. X        a color map
  2010. X
  2011. XPUTPICT.H, PutPict.c     
  2012. X
  2013. X        given a bitmap and a color map, save it as
  2014. X        an ILBM file.
  2015. X
  2016. XGIO.H, Gio.c    generic I/O speedup package.  Attempts to speed
  2017. X        disk I/O by buffering writes and reads.
  2018. X
  2019. Xgiocall.c    sample call to gio.
  2020. X
  2021. Xilbmdump.c    reads in ILBM file, prints out ascii representation
  2022. X        for including in C files.
  2023. X
  2024. Xbmprintc.c    prints out a C-language representation of data for
  2025. X        a bitmap.
  2026. X
  2027. X
  2028. X
  2029. XExample Diagrams
  2030. X
  2031. XHere's a box diagram for an example IFF file, a raster image FORM 
  2032. XILBM. This FORM contains a bitmap header property chunk BMHD, a color 
  2033. Xmap property chunk CMAP, and a raster data chunk BODY. This particular 
  2034. Xraster is 320 x 200 pixels x 3 bit planes uncompressed. The "0" after 
  2035. Xthe CMAP chunk represents a zero pad byte; included since the CMAP 
  2036. Xchunk has an odd length. The text to the right of the diagram shows 
  2037. Xthe outline that would be printed by the IFFCheck utility program 
  2038. Xfor this particular file.
  2039. X
  2040. X    +-----------------------------------+
  2041. X    |'FORM'        24070            |    FORM 24070 IBLM
  2042. X    +-----------------------------------+
  2043. X    |'ILBM'                    |
  2044. X    +-----------------------------------+
  2045. X    | +-------------------------------+ |
  2046. X    | | 'BMHD'    20          | |    .BMHD  20
  2047. X    | | 320, 200, 0, 0, 3, 0, 0, ...  | |
  2048. X    | + ------------------------------+ |
  2049. X    | | 'CMAP'    21              | |    .CMAP  21
  2050. X    | | 0, 0, 0; 32, 0, 0; 64,0,0; .. | |
  2051. X    | +-------------------------------+ |
  2052. X    | 0                    |
  2053. X    +-----------------------------------+
  2054. X    |'BODY'        24000            |    .BODY 24000
  2055. X    |0, 0, 0, ...                |
  2056. X    +-----------------------------------+
  2057. X
  2058. XThis second diagram shows a LIST of two FORMs ILBM sharing a common 
  2059. XBMHD property and a common CMAP property. Again, the text on the right 
  2060. Xis an outline  a la IFFCheck.
  2061. X
  2062. X
  2063. X     +-----------------------------------------+
  2064. X     |'LIST'        48114                      |  LIST  48114  AAAA
  2065. X     +-----------------------------------------+
  2066. X     |'AAAA'                       |  .PROP  62  ILBM
  2067. X     |    +-----------------------------------+  |
  2068. X     |  |'PROP'        62            |  |  
  2069. X     |  +-----------------------------------+  |
  2070. X     |    |'ILBM'                    |  |
  2071. X     |    +-----------------------------------+  |
  2072. X     |    | +-------------------------------+ |  |
  2073. X     |    | | 'BMHD'    20          | |  |  ..BMHD  20
  2074. X     |    | | 320, 200, 0, 0, 3, 0, 0, ...  | |  |
  2075. X     |    | | ------------------------------+ |  |
  2076. X     |    | | 'CMAP'    21              | |  |  ..CMAP  21
  2077. X     |    | | 0, 0, 0; 32, 0, 0; 64,0,0; .. | |  |
  2078. X     |    | +-------------------------------+ |  |
  2079. X     |    | 0                    |  |
  2080. X     |    +-----------------------------------+  |
  2081. X     |    +-----------------------------------+  |
  2082. X     |    |'FORM'        24012            |  |  .FORM  24012  ILBM
  2083. X     |    +-----------------------------------+  |
  2084. X     |    |'ILBM'                    |  |  
  2085. X     |    +-----------------------------------+  |
  2086. X     |    |  +-----------------------------+  |  |
  2087. X     |    |  |'BODY'        24000    |  |  |  ..BODY  24000
  2088. X     |    |  |0, 0, 0, ...         |  |  |
  2089. X     |    |  +-----------------------------+  |  |
  2090. X     |    +-----------------------------------+  |
  2091. X     |    +-----------------------------------+  |
  2092. X     |    |'FORM'        24012            |  |  .FORM  24012  ILBM
  2093. X     |    +-----------------------------------+  |
  2094. X     |    |'ILBM'                    |  |
  2095. X     |    +-----------------------------------+  |
  2096. X     |    |  +-----------------------------+  |  |
  2097. X     |    |  |'BODY'        24000    |  |  |  ..BODY  24000
  2098. X     |    |  |0, 0, 0, ...         |  |  |
  2099. X     |    |  +-----------------------------+  |  |
  2100. X     |    +-----------------------------------+  |
  2101. X     +-----------------------------------------+
  2102. X
  2103. X
  2104. X
  2105. XAppendix B. Standards Committee
  2106. X
  2107. XThe following people contributed to the design of this IFF standard:
  2108. X
  2109. XBob "Kodiak" Burns, Commodore-Amiga
  2110. XR. J. Mical, Commodore-Amiga
  2111. XJerry Morrison, Electronic Arts
  2112. XGreg Riker, Electronic Arts
  2113. XSteve Shaw, Electronic Arts
  2114. XBarry Walsh, Commodore-Amiga
  2115. //END
  2116. echo x - ftxt
  2117. sed 's/^X//' > ftxt << '//END'
  2118. X"FTXT" IFF Formatted Text
  2119. X
  2120. XDate:    November 15, 1985
  2121. XFrom:    Steve Shaw and Jerry Morrison, Electronic Arts and 
  2122. X    Bob "Kodiak" Burns, Commodore-Amiga
  2123. XStatus:    Draft 2.6
  2124. X
  2125. XDRAFT                 DRAFT             DRAFT               
  2126. XDRAFT                 DRAFT        DRAFT    
  2127. X
  2128. X1. Introduction
  2129. X
  2130. XThis memo is the IFF supplement for FORM FTXT. An FTXT is an IFF "data 
  2131. Xsection" or "FORM type" which can be an IFF file or a part of one containing 
  2132. Xa stream of text plus optional formatting information."EA IFF 85" 
  2133. Xis Electronic Arts' standard for interchange format files. (See the 
  2134. XIFF reference.)
  2135. X
  2136. XAn FTXT is an archival and interchange representation designed for 
  2137. Xthree uses. The simplest use is for a "console device" or "glass teletype" 
  2138. X(the minimal 2-D text layout means): a stream of "graphic" ("printable") 
  2139. Xcharacters plus positioning characters "space" ("SP") and line terminator 
  2140. X("LF"). This is not intended for cursor movements on a screen although 
  2141. Xit does not conflict with standard cursor-moving characters. The second 
  2142. Xuse is text that has explicit formatting information (or "looks") 
  2143. Xsuch as font family and size, typeface, etc. The third use is as the 
  2144. Xlowest layer of a structured document that also has "inherited" styles 
  2145. Xto implicitly control character looks. For that use, FORMs FTXT would 
  2146. Xbe embedded within a future document FORM type. The beauty of FTXT 
  2147. Xis that these three uses are interchangeable, that is, a program written 
  2148. Xfor one purpose can read and write the others' files. So a word processor 
  2149. Xdoes not have to write a separate plain text file to communicate with 
  2150. Xother programs.
  2151. X
  2152. XText is stored in one or more "CHRS" chunks inside an FTXT. Each CHRS 
  2153. Xcontains a stream of 8-bit text compatible with ISO and ANSI data 
  2154. Xinterchange standards. FTXT uses just the central character set from 
  2155. Xthe ISO/ANSI standards. (These two standards are henceforth called 
  2156. X"ISO/ANSI" as in "see the ISO/ANSI reference".)
  2157. X
  2158. XSince it's possible to extract just the text portions from future 
  2159. Xdocument FORM types, programs can exchange data without having to 
  2160. Xsave both plain text and formatted text representations.
  2161. X
  2162. XCharacter looks are stored as embedded control sequences within CHRS 
  2163. Xchunks. This document specifies which class of control sequences to 
  2164. Xuse: the CSI group. This document does not yet specify their meanings, 
  2165. Xe.g. which one means "turn on italic face". Consult ISO/ANSI.
  2166. X
  2167. XSection 2 defines the chunk types character stream "CHRS" and font 
  2168. Xspecifier "FONS". These are the "standard" chunks. Specialized chunks 
  2169. Xfor private or future needs can be added later. Section 3 outlines 
  2170. Xan FTXT reader program that strips a document down to plain unformatted 
  2171. Xtext. Appendix A is a code table for the 8-bit ISO/ANSI character 
  2172. Xset used here. Appendix B is an example FTXT shown as a box diagram. 
  2173. XAppendix C is a racetrack diagram of the syntax of ISO/ANSI control 
  2174. Xsequences.
  2175. X
  2176. X
  2177. XReference:
  2178. X
  2179. XAmiga[tm] is a trademark of Commodore-Amiga, Inc.
  2180. X
  2181. XElectronic Arts[tm] is a trademark of Electronic Arts.
  2182. X
  2183. XIFF: "EA IFF 85" Standard for Interchange Format Files describes the 
  2184. Xunderlying conventions for all IFF files.
  2185. X
  2186. XISO/ANSI: ISO/DIS 6429.2 and ANSI X3.64-1979. International Organization 
  2187. Xfor Standardization (ISO) and American National Standards Institute 
  2188. X(ANSI) data-interchange standards. The relevant parts of these two 
  2189. Xstandards documents are identical. ISO standard 2022 is also relevant.
  2190. X
  2191. X
  2192. X2. Standard Data and Property Chunks
  2193. X
  2194. XThe main contents of a FORM FTXT is in its character stream "CHRS" 
  2195. Xchunks. Formatting property chunks may also appear. The only formatting 
  2196. Xproperty yet defined is "FONS", a font specifier. A FORM FTXT with 
  2197. Xno CHRS represents an empty text stream. A FORM FTXT may contain nested 
  2198. XIFF FORMs, LISTs, or CATs, although a "stripping" reader (see section 
  2199. X3) will ignore them.
  2200. X
  2201. XCharacter Set
  2202. X
  2203. XFORM FTXT uses the core of the 8-bit character set defined by the 
  2204. XISO/ANSI standards cited at the start of this document. (See Appendix 
  2205. XA for a character code table.) This character set is divided into 
  2206. Xtwo "graphic" groups plus two "control" groups. Eight of the control 
  2207. Xcharacters begin ISO/ANSI standard control sequences. (See "Control 
  2208. XSequences", below.) Most control sequences and control characters 
  2209. Xare reserved for future use and for compatibility with ISO/ANSI. Current 
  2210. Xreader programs should skip them.
  2211. X
  2212. X%    C0 is the group of control characters in the range NUL (hex 
  2213. X0) through hex 1F. Of these, only LF (hex 0A) and ESC (hex 1B) are 
  2214. Xsignificant. ESC begins a control sequence. LF is the line terminator, 
  2215. Xmeaning "go to the first horizontal position of the next line". All 
  2216. Xother C0 characters are not used. In particular, CR (hex 0D) is not 
  2217. Xrecognized as a line terminator.
  2218. X
  2219. X%    G0 is the group of graphic characters in the range hex 20 through 
  2220. Xhex 7F. SP (hex 20) is the space character. DEL (hex 7F) is the delete 
  2221. Xcharacter which is not used. The rest are the standard ASCII printable 
  2222. Xcharacters "!" (hex 21) through "~" (hex 7E).
  2223. X
  2224. X%    C1 is the group of extended control characters in the range 
  2225. Xhex 80 through hex 9F. Some of these begin control sequences. The 
  2226. Xcontrol sequence starting with CSI (hex 9B) is used for FTXT formatting. 
  2227. XAll other control sequences and C1 control characters are unused.
  2228. X
  2229. X%    G1 is the group of extended graphic characters in the range 
  2230. XNBSP (hex A0) through "X" (hex FF). It is one of the alternate graphic 
  2231. Xgroups proposed for ISO/ANSI standardization.
  2232. X
  2233. XControl Sequences
  2234. X
  2235. XEight of the control characters begin ISO/ANSI standard "control sequences" 
  2236. X(or "escape sequences"). These sequences are described below and diagrammed 
  2237. Xin Appendix C.
  2238. X
  2239. XG0    ::= (SP through DEL)
  2240. XG1    ::= (NBSP through "X")
  2241. X
  2242. XESC-Seq    ::= ESC (SP through "/")* ("0" through "~")
  2243. XShiftToG2    ::= SS2 G0
  2244. XShiftToG3    ::= SS3 G0
  2245. XCSI-Seq    ::= CSI (SP through "?")* ("@" through "~")
  2246. XDCS-Seq    ::= (DCS | OSC | PM | APC) (SP through "~" | G1)* ST
  2247. X
  2248. X"ESC-Seq" is the control sequence ESC (hex 1B), followed by zero or 
  2249. Xmore characters in the range SP through "/S (hex 20 through hex 2F), 
  2250. Xfollowed by a character in the range "0" through "~" (hex 30 through 
  2251. Xhex 7E). These sequences are reserved for future use and should be 
  2252. Xskipped by current FTXT reader programs.
  2253. X
  2254. XSS2 (hex 8E) and SS3 (hex 8F) shift the single following G0 character 
  2255. Xinto yet-to-be-defined graphic sets G2 and G3, respectively. These 
  2256. Xsequences should not be used until the character sets G2 and G3 are 
  2257. Xstandardized. A reader may simply skip the SS2 or SS3 (taking the 
  2258. Xfollowing character as a corresponding G0 character) or replace the 
  2259. Xtwo-character sequence with a character like "?" to mean "absent".
  2260. X
  2261. XFTXT uses "CSI-Seq" control sequences to store character formatting 
  2262. X(font selection by number, type face, and text size) and perhaps layout 
  2263. Xinformation (position and rotation). "CSI-Seq" control sequences start 
  2264. Xwith CSI (the "control sequence introducer", hex 9B). Syntactically, 
  2265. Xthe sequence includes zero or more characters in the range SP through 
  2266. X"?" (hex 20 through hex 3F) and a concluding character in the range 
  2267. X"@" through "~" (hex 40 through hex 7E). These sequences may be skipped 
  2268. Xby a minimal FTXT reader, i.e. one that ignores formatting information.
  2269. X
  2270. XNote: A future FTXT standardization document will explain the uses 
  2271. Xof CSI-Seq sequences for setting character face (light weight vs. 
  2272. Xmedium vs. bold, italic vs. upright, height, pitch, position, and 
  2273. Xrotation). For now, consult the ISO/ANSI references.
  2274. X
  2275. X"DCS-Seq" is the control sequences starting with DCS (hex 90), OSC 
  2276. X(hex 9D), PM (hex 9E), or APC (hex 9F), followed by zero or more characters 
  2277. Xeach of which is in the range SP through "~" (hex 20 through hex 7E) 
  2278. Xor else a G1 character, and terminated by an ST (hex 9C). These sequences 
  2279. Xare reserved for future use and should be skipped by current FTXT 
  2280. Xreader programs.
  2281. X
  2282. XData Chunk CHRS
  2283. X
  2284. XA CHRS chunk contains a sequence of 8-bit characters abiding by the 
  2285. XISO/ANSI standards cited at the start of this document. This includes 
  2286. Xthe character set and control sequences as described above and summarized 
  2287. Xin Appendicies A and C.
  2288. X
  2289. XA FORM FTXT may contain any number of CHRS chunks. Taken together, 
  2290. Xthey represent a single stream of textual information. That is, the 
  2291. Xcontents of CHRS chunks are effectively concatenated except that (1) 
  2292. Xeach control sequence must be completely within a single CHRS chunk, 
  2293. Xand (2) any formatting property chunks appearing between two CHRS 
  2294. Xchunks affects the formatting of the latter chunk's text. Any formatting 
  2295. Xsettings set by control sequences inside a CHRS carry over to the 
  2296. Xnext CHRS in the same FORM FTXT. All formatting properties stop at 
  2297. Xthe end of the FORM since IFF specifies that adjacent FORMs are independent 
  2298. Xof each other (although not independent of any properties inherited 
  2299. Xfrom an enclosing LIST or FORM).
  2300. X
  2301. XProperty Chunk FONS
  2302. X
  2303. XThe optional property "FONS" holds a FontSpecifier as defined in the 
  2304. XC declaration below. It assignes a font to a numbered "font register" 
  2305. Xso it can be referenced by number within subsequent CHRS chunks. (This 
  2306. Xfunction is not provided within the ISO and ANSI standards.) The font 
  2307. Xspecifier gives both a name and a description for the font so the 
  2308. Xrecipient program can do font substitution.
  2309. X
  2310. XBy default, CHRS text uses font 1 until it selects another font. A 
  2311. Xminimal text reader always uses font 1. If font 1 hasn't been specified, 
  2312. Xthe reader may use the local system font as font 1.
  2313. X
  2314. X    typedef struct {
  2315. X        UBYTE id;    
  2316. X            /* 0 through 9 is a font id number referenced by an 
  2317. X             * SGR control sequence selective parameter of 10 
  2318. X             * through 19. Other values are reserved for future 
  2319. X             * standardization.    
  2320. X             */
  2321. X        UBYTE pad1;   /* reserved for future use; store 0 here */
  2322. X        UBYTE proportional;    
  2323. X            /* proportional font? 0 = unknown, 1 = no, 2 = yes */ 
  2324. X        UBYTE serif;        
  2325. X            /* serif font? 0 = unknown, 1 = no, 2 = yes */
  2326. X        char name[];    
  2327. X            /* A NULL-terminated string naming preferred font. */
  2328. X        } FontSpecifier;
  2329. X    
  2330. XFields are filed in the order shown. The UBYTE fields are byte-packed 
  2331. X(2 per 16-bit word). The field pad1 is reserved for future standardization. 
  2332. XPrograms should store 0 there for now.
  2333. X
  2334. XThe field proportional indicates if the desired font is proportional 
  2335. Xwidth as opposed to fixed width. The field serif indicates if the 
  2336. Xdesired font is serif as opposed to sans serif. [Issue: Discuss font 
  2337. Xsubstitution!]
  2338. X
  2339. XFuture Properties
  2340. X
  2341. XNew optional property chunks may be defined in the future to store 
  2342. Xadditional formatting information. They will be used to represent 
  2343. Xformatting not encoded in standard ISO/ANSI control sequences and 
  2344. Xfor "inherited" formatting in structured documents. Text orientation 
  2345. Xmight be one example.
  2346. X
  2347. XPositioning Units
  2348. X
  2349. XUnless otherwise specified, position and size units used in FTXT formatting 
  2350. Xproperties and control sequences are in decipoints (720 decipoints/inch). 
  2351. XThis is ANSI/ISO Positioning Unit Mode (PUM) 2. While a metric standard 
  2352. Xmight be nice, decipoints allow the existing U.S.A. typographic units 
  2353. Xto be encoded easily, e.g. "12 points" is "120 decipoints".
  2354. X
  2355. X
  2356. X3. FTXT Stripper
  2357. X
  2358. XAn FTXT reader program can read the text and ignore all formatting 
  2359. Xand structural information in a document FORM that uses FORMs FTXT 
  2360. Xfor the leaf nodes. This amounts to stripping a document down to a 
  2361. Xstream of plain text. It would do this by skipping over all chunks 
  2362. Xexcept FTXT.CHRS (CHRS chunks found inside a FORM FTXT) and within 
  2363. Xthe FTXT.CHRS chunks skipping all control characters and control sequences. 
  2364. X(Appendix C diagrams this text scanner.) It may also read FTXT.FONS 
  2365. Xchunks to find a description for font 1.
  2366. X
  2367. XHere's a Pascal-ish program for an FTXT stripper. Given a FORM (a 
  2368. Xdocument of some kind), it scans for all FTXT.CHRS chunks. This would 
  2369. Xlikely be applied to the first FORM in an IFF file.
  2370. X
  2371. XPROCEDURE ReadFORM4CHRS();    {Read an IFF FORM for FTXT.CHRS chunks.}
  2372. XBEGIN
  2373. XIF the FORM's subtype = "FTXT"
  2374. X    THEN ReadFTXT4CHRS()
  2375. X    ELSE WHILE something left to read in the FORM DO BEGIN
  2376. X            read the next chunk header;
  2377. X            CASE the chunk's ID OF
  2378. X                "LIST", "CAT ": ReadCAT4CHRS();
  2379. X                "FORM": ReadFORM4CHRS();
  2380. X                OTHERWISE skip the chunk's body;
  2381. X                END
  2382. X            END
  2383. XEND;
  2384. X
  2385. X{Read a LIST or CAT for all FTXT.CHRS chunks.}
  2386. XPROCEDURE ReadCAT4CHRS();
  2387. X    BEGIN
  2388. XWHILE something left to read in the LIST or CAT DO BEGIN
  2389. X    read the next chunk header;
  2390. X    CASE the chunk's ID OF
  2391. X        "LIST", "CAT ": ReadCAT4CHRS();
  2392. X        "FORM": ReadFORM4CHRS();
  2393. X        "PROP": IF we're reading a LIST AND the PROP's subtype = 
  2394. X"FTXT"
  2395. X                    THEN read the PROP for "FONS" chunks;
  2396. X        OTHERWISE error--malformed IFF file;
  2397. X        END
  2398. X    END
  2399. XEND;
  2400. X
  2401. XPROCEDURE ReadFTXT4CHRS();    {Read a FORM FTXT for CHRS chunks.}
  2402. XBEGIN
  2403. XWHILE something left to read in the FORM FTXT DO BEGIN
  2404. X    read the next chunk header;
  2405. X    CASE the chunk's ID OF
  2406. X        "CHRS": ReadCHRS();
  2407. X        "FONS": BEGIN
  2408. X            read the chunk's contents into a FontSpecifier variable;
  2409. X            IF the font specifier's id = 1 THEN use this font;
  2410. X            END;
  2411. X        OTHERWISE skip the chunk's body;
  2412. X        END
  2413. X    END
  2414. XEND;
  2415. X
  2416. X{Read an FTXT.CHRS. Skip all control sequences and unused control 
  2417. Xchars.}
  2418. XPROCEDURE ReadCHRS();
  2419. XBEGIN
  2420. XWHILE something left to read in the CHRS chunk DO
  2421. X    CASE read the next character OF
  2422. X        LF:  start a new output line;
  2423. X        ESC: SkipControl([' '..'/'], ['0'..'~']);
  2424. X        IN [' '..'~'], IN [NBSP..'X']: output the character;
  2425. X        SS2, SS3: ;    {Just handle the following G0 character 
  2426. X                directly, ignoring the shift to G2 or G3.}
  2427. X        CSI: SkipControl([' '..'?'], ['@'..'~']);
  2428. X        DCS, OSC, PM, APC: SkipControl([' '..'~'] + [NBSP..'X'], [ST]);
  2429. X        END
  2430. XEND;
  2431. X
  2432. X{Skip a control sequence of the format (rSet)* (tSet), i.e. any number 
  2433. Xof characters in the set rSet followed by a character in the set tSet.}
  2434. XPROCEDURE SkipControl(rSet, tSet);
  2435. XVAR c: CHAR;
  2436. XBEGIN
  2437. XREPEAT c := read the next character
  2438. X    UNTIL c NOT IN rSet;
  2439. XIF c NOT IN tSet
  2440. X    THEN put character c back into the input stream;
  2441. XEND
  2442. X
  2443. XThe following program is an optimized version of the above routines 
  2444. XReadFORM4CHRS and ReadCAT4CHRS for the case where you're ignoring 
  2445. Xfonts as well as formatting. It takes advantage of certain facts of 
  2446. Xthe IFF format to read a document FORM and its nested FORMs, LISTs, 
  2447. Xand CATs without a stack. In other words, it's a hack that ignores 
  2448. Xall fonts and faces to cheaply get to the plain text of the document.
  2449. X
  2450. X{Cheap scan of an IFF FORM for FTXT.CHRS chunks.}
  2451. XPROCEDURE ScanFORM4CHRS();
  2452. XBEGIN
  2453. XIF the document FORM's subtype = "FTXT"
  2454. X    THEN ReadFTXT4CHRS()
  2455. X    ELSE WHILE something left to read in the FORM DO BEGIN
  2456. X        read the next chunk header;
  2457. X        IF it's a group chunk (LIST, FORM, PROP, or CAT)
  2458. X            THEN read its subtype ID;
  2459. X        CASE the chunk's ID OF
  2460. X            "LIST", "CAT ":;    {NOTE: See explanation below.*}
  2461. X            "FORM": IF this FORM's subtype = "FTXT" THEN 
  2462. X                        ReadFTXT4CHRS()
  2463. X                ELSE;    {NOTE: See explanation below.*}
  2464. X            OTHERWISE skip the chunk's body;
  2465. X            END
  2466. X        END
  2467. XEND;
  2468. X
  2469. X*Note: This implementation is subtle. After reading a group header 
  2470. Xother than FORM FTXT it just continues reading. This amounts to reading 
  2471. Xall the chunks inside that group as if they weren't nested in a group.
  2472. X
  2473. X
  2474. XAppendix A: Character Code Table
  2475. X
  2476. XThis table corresponds to the ISO/DIS 6429.2 and ANSI X3.64-1979 8-bit 
  2477. Xcharacter set standards. Only the core character set of those standards 
  2478. Xis used in FTXT.
  2479. X
  2480. XTwo G1 characters aren't defined in the standards and are shown as 
  2481. Xdark gray entries in this table. Light gray shading denotes control 
  2482. Xcharacters. (DEL is a control character although it belongs to the 
  2483. Xgraphic group G0.) The following five rare G1 characters are left 
  2484. Xblank in the table below due to limitations of available fonts: hex 
  2485. XA8, D0, DE, F0, and FE.
  2486. X
  2487. X
  2488. X
  2489. X   ISO/DIS 6429.2 and ANSI X3.64-1979 Character Code Table
  2490. X
  2491. X
  2492. X  (figure named "TextTable", viewable by ShowILBM or SeeILBM)
  2493. X
  2494. X
  2495. X[_____] [_______________________] [_____] [____________________________]
  2496. XControl   Grapic Group            Control   Graphic Group
  2497. X Group        G0                   Group         G1
  2498. X  C0                                C1
  2499. X
  2500. X"NBSP" is a "non-breaking space"
  2501. X"SHY" is a "soft-hyphen"
  2502. X
  2503. X
  2504. X
  2505. XAppendix B. FTXT Example
  2506. X
  2507. XHere's a box diagram for a simple example: "The quick brown fox jumped.Four 
  2508. Xscore and seven", written in a proportional serif font named "Roman".
  2509. X
  2510. X
  2511. X          +-----------------------------------+   
  2512. X          |'FORM'        24070            |     FORM  24070  ILBM
  2513. X          +-----------------------------------+   
  2514. X          |'ILBM'                    |     
  2515. X          +-----------------------------------+   
  2516. X          | +-------------------------------+ |   
  2517. X          | | 'BMHD'    20          | |     .BMHD  20
  2518. X          | | 320, 200, 0, 0, 3, 0, 0, ...  | |   
  2519. X          | | ------------------------------+ |   
  2520. X          | | 'CMAP'    21              | |     .CMAP  21
  2521. X          | | 0, 0, 0; 32, 0, 0; 64,0,0; .. | |   
  2522. X          | +-------------------------------+ |   
  2523. X          | +-------------------------------+ |   
  2524. X          | |'BODY'        24000     | |     .BODY  24000
  2525. X          | |0, 0, 0, ...              | |   
  2526. X          | +-------------------------------+ |   
  2527. X          +-----------------------------------+   
  2528. X
  2529. XThe "0" after the CMAP chunk is a pad byte.
  2530. X
  2531. X
  2532. X
  2533. X
  2534. XAppendix B. Standards Committee
  2535. X
  2536. XThe following people contributed to the design of this IFF standard:
  2537. X
  2538. XBob "Kodiak" Burns, Commodore-Amiga
  2539. XR. J. Mical, Commodore-Amiga
  2540. XJerry Morrison, Electronic Arts
  2541. XGreg Riker, Electronic Arts
  2542. XSteve Shaw, Electronic Arts
  2543. XBarry Walsh, Commodore-Amiga
  2544. X
  2545. X
  2546. X
  2547. XAppendix C. ISO/ANSI Control Sequences
  2548. X
  2549. XThis is a racetrack diagram of the ISO/ANSI characters and control 
  2550. Xsequences as used in FTXT CHRS chunks.
  2551. X
  2552. X    line terminator   
  2553. X-----+-------------------> LF --------------------------------------->
  2554. X     |    ESC-Seq 
  2555. X     +-------------------> ESC ---+>----------------+--> 0 thru ~ --->
  2556. X     |                  |            |
  2557. X     |                  +-- SP thru / <---+
  2558. X     |  printable
  2559. X     +---------------+---> SP thru ~ --+->--------------------------->
  2560. X     |             |               |
  2561. X     |             +---> G1 -------->+
  2562. X     |  shift to G2                
  2563. X     +-------------------> SS2 ----> G0 ---> (produces a G2 character)
  2564. X     |  shift to G3                
  2565. X     +-------------------> SS3 ----> G0 ---> (produces a G3 character)
  2566. X     |    CSI-Seq 
  2567. X     +-------------------> CSI ---+>----------------+--> @ thru ~ --->
  2568. X     |                  |            |
  2569. X     |                  +-- SP thru ? <---+
  2570. X     |    DCS-Seq 
  2571. X     +----------> DCS,OSC,PM,or APC --+>-------------+--+-> ST -+----> 
  2572. X     |                      |                 |  |       |
  2573. X     |                      +- SP thru ~ <-+  +-> G1 -+
  2574. X     |  discard
  2575. X     +----------> any other character ------------------------------->
  2576. X
  2577. X
  2578. X
  2579. XOf the various control sequences, only CSI-Seq is used for FTXT character 
  2580. Xformatting information. The others are reserved for future use and 
  2581. Xfor compatibility with ISO/ANSI standards. Certain character sequences 
  2582. Xare syntactically malformed, e.g. CSI followed by a C0, C1, or G1 
  2583. Xcharacter. Writer programs should not generate reserved or malformed 
  2584. Xsequences and reader programs should skip them.
  2585. X
  2586. XConsult the ISO/ANSI standards for the meaning of the CSI-Seq control 
  2587. Xsequences.
  2588. X
  2589. XThe two character set shifts SS2 and SS3 may be used when the graphic 
  2590. Xcharacter groups G2 and G3 become standardized.
  2591. X
  2592. //END
  2593. echo x - ilbm
  2594. sed 's/^X//' > ilbm << '//END'
  2595. X"ILBM" IFF Interleaved Bitmap
  2596. X
  2597. XDate:    January 17, 1986
  2598. XFrom:    Jerry Morrison, Electronic Arts
  2599. XStatus:    Released and in use
  2600. X
  2601. X1. Introduction
  2602. X
  2603. X"EA IFF 85" is Electronic Arts' standard for interchange format files. 
  2604. X"ILBM" is a format for a 2 dimensional raster graphics image, specifically 
  2605. Xan InterLeaved bitplane BitMap image with color map. An ILBM is an 
  2606. XIFF "data section" or "FORM type", which can be an IFF file or a part 
  2607. Xof one. (See the IFF reference.)
  2608. X
  2609. XAn ILBM is an archival representation designed for three uses. First, 
  2610. Xa standalone image that specifies exactly how to display itself (resolution, 
  2611. Xsize, color map, etc.). Second, an image intended to be merged into 
  2612. Xa bigger picture which has its own depth, color map, and so on. And 
  2613. Xthird, an empty image with a color map selection or "palette" for 
  2614. Xa paint program. ILBM is also intended as a building block for composite 
  2615. XIFF FORMs like "animation sequence" and "structured graphics". Some 
  2616. Xuses of ILBM will be to preserve as much information as possible across 
  2617. Xdisparate environments. Other uses will be to store data for a single 
  2618. Xprogram or highly cooperative programs while maintaining subtle details. 
  2619. XSo we're trying to accomplish a lot with this one format.
  2620. X
  2621. XThis memo is the IFF supplement for FORM ILBM. Section 2 defines the 
  2622. Xpurpose and format of property chunks bitmap header "BMHD", color 
  2623. Xmap "CMAP", hotspot "GRAB", destination merge data "DEST", sprite 
  2624. Xinformation "SPRT", and Commodore Amiga viewport mode "CAMG". Section 
  2625. X3 defines the standard data chunk "BODY". These are the "standard" 
  2626. Xchunks. Section 4 defines the nonstandard color range data chunk "CRNG". 
  2627. XAdditional specialized chunks like texture pattern can be added later. 
  2628. XThe ILBM syntax is summarized in Appendix A as a regular expression 
  2629. Xand in Appendix B as a box diagram. Appendix C explains the optional 
  2630. Xrun encoding scheme. Appendix D names the committee responsible for 
  2631. Xthis FORM ILBM standard.
  2632. X
  2633. XDetails of the raster layout are given in part 3, "Standard Data Chunk". 
  2634. XSome elements are based on the Commodore Amiga hardware but generalized 
  2635. Xfor use on other computers. An alternative to ILBM would be appropriate 
  2636. Xfor computers with true color data in each pixel.
  2637. X
  2638. XReference:
  2639. X
  2640. X"EA IFF 85" Standard for Interchange Format Files describes the underlying 
  2641. Xconventions for all IFF files.
  2642. X
  2643. XAmiga[tm] is a trademark of Commodore-Amiga, Inc.
  2644. XElectronic Arts[tm] is a trademark of Electronic Arts.
  2645. XMacintosh[tm] is a trademark licensed to Apple Computer, Inc.
  2646. XMacPaint[tm] is a trademark of Apple Computer, Inc.
  2647. X
  2648. X
  2649. X2. Standard Properties
  2650. X
  2651. XThe required property "BMHD" and any optional properties must appear 
  2652. Xbefore any "BODY" chunk. (Since an ILBM has only one BODY chunk, any 
  2653. Xfollowing properties are superfluous.) Any of these properties may 
  2654. Xbe shared over a LIST of FORMs IBLM by putting them in a PROP ILBM. 
  2655. X(See the "EA IFF 85" memo.)
  2656. X
  2657. XBMHD
  2658. X
  2659. XThe required property "BMHD" holds a BitMapHeader as defined in these 
  2660. XC declarations and following documentation. It describes the dimensions 
  2661. Xand encoding of the image, including data necessary to understand 
  2662. Xthe BODY chunk to follow.
  2663. X
  2664. Xtypedef UBYTE Masking;     /* Choice of masking technique. */
  2665. X
  2666. X#define mskNone    0
  2667. X#define mskHasMask    1
  2668. X#define mskHasTransparentColor    2
  2669. X#define mskLasso    3
  2670. X
  2671. Xtypedef UBYTE Compression;    
  2672. X    /* Choice of compression algorithm applied to the rows of all 
  2673. X     * source and mask planes. "cmpByteRun1" is the byte run encoding 
  2674. X     * described in Appendix C. Do not compress across rows! */
  2675. X#define cmpNone    0
  2676. X#define cmpByteRun1    1
  2677. X
  2678. Xtypedef struct {
  2679. X    UWORD w, h;    /* raster width & height in pixels    */
  2680. X    WORD  x, y;    /* pixel position for this image    */
  2681. X    UBYTE nPlanes;    /* # source bitplanes    */
  2682. X    Masking masking;
  2683. X    Compression compression;
  2684. X    UBYTE pad1;    /* unused; for consistency, put 0 here    */
  2685. X    UWORD transparentColor;    /* transparent "color number" (sort of)    */
  2686. X    UBYTE xAspect, yAspect;    /* pixel aspect, a ratio width : height    */
  2687. X    WORD  pageWidth, pageHeight;    /* source "page" size in pixels    */
  2688. X    } BitMapHeader;
  2689. X
  2690. XFields are filed in the order shown. The UBYTE fields are byte-packed.
  2691. X
  2692. XThe fields w and h indicate the size of the image rectangle in pixels. 
  2693. XEach row of the image is stored in an integral number of 16 bit words. 
  2694. XThe number of words per row is Ceiling(w/16). The fields x and y indicate 
  2695. Xthe desired position of this image within the destination picture. 
  2696. XSome reader programs may ignore x and y. A safe default for writing 
  2697. Xan ILBM is (x, y) = (0, 0).
  2698. X
  2699. XThe number of source bitplanes in the BODY chunk (see below) is stored 
  2700. Xin nPlanes. An ILBM with a CMAP but no BODY and nPlanes = 0 is the 
  2701. Xrecommended way to store a color map.
  2702. X
  2703. XNote: Color numbers are color map index values formed by pixels in 
  2704. Xthe destination bitmap, which may be deeper than nPlanes if a DEST 
  2705. Xchunk calls for merging the image into a deeper image.
  2706. X
  2707. XThe field masking indicates what kind of masking is to be used for 
  2708. Xthis image. The value mskNone designates an opaque rectangular image. 
  2709. XThe value mskHasMask means that a mask plane is interleaved with the 
  2710. Xbitplanes in the BODY chunk (see below). The value mskHasTransparentColor 
  2711. Xindicates that pixels in the source planes matching transparentColor 
  2712. Xare to be considered "transparent". (Actually, transparentColor isn't 
  2713. Xa "color number" since it's matched with numbers formed by the source 
  2714. Xbitmap rather than the possibly deeper destination bitmap. Note that 
  2715. Xhaving a transparent color implies ignoring one of the color registers. 
  2716. XSee CMAP, below.) The value mskLasso indicates the reader may construct 
  2717. Xa mask by lassoing the image as in MacPaint*. To do this, put a 1 
  2718. Xpixel border of transparentColor around the image rectangle. Then 
  2719. Xdo a seed fill from this border. Filled pixels are to be transparent.
  2720. X
  2721. XIssue: Include in an appendix an algorithm for converting a transparent 
  2722. Xcolor to a mask plane, and maybe a lasso algorithm.
  2723. X
  2724. XA code indicating the kind of data compression used is stored in compression. 
  2725. XBeware that using data compression makes your data unreadable by programs 
  2726. Xthat don't implement the matching decompression algorithm. So we'll 
  2727. Xemploy as few compression encodings as possible. The run encoding 
  2728. XbyteRun1 is documented in Appendix C, below.
  2729. X
  2730. XThe field pad1 is a pad byte and must be set to 0 for consistency. 
  2731. XThis field could get used in the future.
  2732. X
  2733. XThe transparentColor specifies which bit pattern means "transparent".  
  2734. XThis only applies if masking is mskHasTransparentColor or mskLasso 
  2735. X(see above). Otherwise, transparentColor should be 0.
  2736. X
  2737. XThe pixel aspect ratio is stored as a ratio in the two fields xAspect 
  2738. Xand yAspect. This may be used by programs to compensate for different 
  2739. Xaspects or to help interpret the fields w, h, x, y, pageWidth, and 
  2740. XpageHeight, which are in units of pixels. The fraction xAspect/yAspect 
  2741. Xrepresents a pixel's width/height. It's recommended that your programs 
  2742. Xstore proper fractions in BitMapHeaders, but aspect ratios can always 
  2743. Xbe correctly compared with the the test
  2744. X
  2745. XxAspect%yDesiredAspect = yAspect%xDesiredAspect
  2746. X
  2747. XTypical values for aspect ratio are width : height = 10 : 11 (Amiga 
  2748. X320 x 200 display) and 1 : 1 (Macintosh*).
  2749. X
  2750. XThe size in pixels of the source "page" (any raster device) is stored 
  2751. Xin pageWidth and pageHeight, e.g. (320, 200) for a low resolution 
  2752. XAmiga display. This information might be used to scale an image or 
  2753. Xto automatically set the display format to suit the image. (The image 
  2754. Xcan be larger than the page.)
  2755. X
  2756. XCMAP
  2757. X
  2758. XThe optional (but encouraged) property "CMAP" stores color map data 
  2759. Xas triplets of red, green, and blue intensity values. The n color 
  2760. Xmap entries ("color registers") are stored in the order 0 through 
  2761. Xn-1, totaling 3n bytes. Thus n is the ckSize/3. Normally, n would 
  2762. Xequal 2nPlanes.
  2763. X
  2764. XA CMAP chunk contains a ColorMap array as defined below. (These typedefs 
  2765. Xassume a C compiler that implements packed arrays of 3-byte elements.)
  2766. X
  2767. Xtypedef struct {
  2768. X    UBYTE red, green, blue;    /* color intensities 0..255 */
  2769. X    } ColorRegister;    /* size = 3 bytes */
  2770. X
  2771. Xtypedef ColorRegister ColorMap[n];    /* size = 3n bytes */
  2772. X
  2773. XThe color components red, green, and blue represent fractional intensity 
  2774. Xvalues in the range 0 through 255 256ths. White is (255, 255, 255) 
  2775. Xand black is (0, 0, 0). If your machine has less color resolution, 
  2776. Xuse the high order bits. Shift each field right on reading (or left 
  2777. Xon writing) and assign it to (from) a field in a local packed format 
  2778. Xlike Color4, below. This achieves automatic conversion of images across 
  2779. Xenvironments with different color resolutions. On reading an ILBM, 
  2780. Xuse defaults if the color map is absent or has fewer color registers 
  2781. Xthan you need. Ignore any extra color registers.
  2782. X
  2783. XThe example type Color4 represents the format of a color register 
  2784. Xin working memory of an Amiga computer, which has 4 bit video DACs. 
  2785. X(The ":4" tells the C compiler to pack the field into 4 bits.)
  2786. X
  2787. Xtypedef struct {
  2788. X    unsigned pad1 :4, red :4, green :4, blue :4;
  2789. X    } Color4;    /* Amiga RAM format. Not filed. */
  2790. X
  2791. XRemember that every chunk must be padded to an even length, so a color 
  2792. Xmap with an odd number of entries would be followed by a 0 byte, not 
  2793. Xincluded in the ckSize.
  2794. X
  2795. XGRAB
  2796. X
  2797. XThe optional property "GRAB" locates a "handle" or "hotspot" of the 
  2798. Ximage relative to its upper left corner, e.g. when used as a mouse 
  2799. Xcursor or a "paint brush". A GRAB chunk contains a Point2D.
  2800. X
  2801. Xtypedef struct {
  2802. X    WORD x, y;    /* relative coordinates (pixels) */
  2803. X    } Point2D;
  2804. X
  2805. XDEST
  2806. X
  2807. XThe optional property "DEST" is a way to say how to scatter zero or 
  2808. Xmore source bitplanes into a deeper destination image. Some readers 
  2809. Xmay ignore DEST.
  2810. X
  2811. XThe contents of a DEST chunk is DestMerge structure:
  2812. X
  2813. Xtypedef struct {
  2814. X    UBYTE depth;    /* # bitplanes in the original source    */
  2815. X    UBYTE pad1;    /* unused; for consistency put 0 here    */
  2816. X    UWORD planePick; /* how to scatter source bitplanes into destination */
  2817. X    UWORD planeOnOff;    /* default bitplane data for planePick    */
  2818. X    UWORD planeMask;    /* selects which bitplanes to store into */
  2819. X    } DestMerge;
  2820. X
  2821. XThe low order depth number of bits in planePick, planeOnOff, and planeMask 
  2822. Xcorrespond one-to-one with destination bitplanes. Bit 0 with bitplane 
  2823. X0, etc. (Any higher order bits should be ignored.) "1" bits in planePick 
  2824. Xmean "put the next source bitplane into this bitplane", so the number 
  2825. Xof "1" bits should equal nPlanes. "0" bits mean "put the corresponding 
  2826. Xbit from planeOnOff into this bitplane". Bits in planeMask gate writing 
  2827. Xto the destination bitplane: "1" bits mean "write to this bitplane" 
  2828. Xwhile "0" bits mean "leave this bitplane alone". The normal case (with 
  2829. Xno DEST property) is equivalent to planePick = planeMask = 2nPlanesJ- 
  2830. X1.
  2831. X
  2832. XRemember that color numbers are formed by pixels in the destination 
  2833. Xbitmap (depth planes deep) not in the source bitmap (nPlanes planes 
  2834. Xdeep).
  2835. X
  2836. XSPRT
  2837. X
  2838. XThe presence of an "SPRT" chunk indicates that this image is intended 
  2839. Xas a sprite. It's up to the reader program to actually make it a sprite, 
  2840. Xif even possible, and to use or overrule the sprite precedence data 
  2841. Xinside the SPRT chunk:
  2842. X
  2843. Xtypedef UWORD SpritePrecedence; /* relative precedence, 0 is the highest */
  2844. X
  2845. XPrecedence 0 is the highest, denoting a sprite that is foremost.
  2846. X
  2847. XCreating a sprite may imply other setup. E.g. a 2 plane Amiga sprite 
  2848. Xwould have transparentColor = 0. Color registers 1, 2, and 3 in the 
  2849. XCMAP would be stored into the correct hardware color registers for 
  2850. Xthe hardware sprite number used, while CMAP color register 0 would 
  2851. Xbe ignored.
  2852. X
  2853. XCAMG
  2854. X
  2855. XA "CAMG" chunk is specifically for the Commodore Amiga computer. It 
  2856. Xstores a LONG "viewport mode". This lets you specify Amiga display 
  2857. Xmodes like "dual playfield" and "hold and modify".
  2858. X3. Standard Data Chunk
  2859. X
  2860. XRaster Layout
  2861. X
  2862. XRaster scan proceeds left-to-right (increasing X) across scan lines, 
  2863. Xthen top-to-bottom (increasing Y) down columns of scan lines. The 
  2864. Xcoordinate system is in units of pixels, where (0,0) is the upper 
  2865. Xleft corner.
  2866. X
  2867. XThe raster is typically organized as bitplanes in memory. The corresponding 
  2868. Xbits from each plane, taken together, make up an index into the color 
  2869. Xmap which gives a color value for that pixel. The first bitplane, 
  2870. Xplane 0, is the low order bit of these color indexes.
  2871. X
  2872. XA scan line is made of one "row" from each bitplane. A row is one 
  2873. XplanesU bits for one scan line, but padded out to a word (2 byte) 
  2874. Xboundary (not necessarily the first word boundary). Within each row, 
  2875. Xsuccessive bytes are displayed in order and the most significant bit 
  2876. Xof each byte is displayed first.
  2877. X
  2878. XA "mask" is an optional "plane" of data the same size (w, h) as a 
  2879. Xbitplane.  It tells how to "cut out" part of the image when painting 
  2880. Xit onto another image."One" bits in the mask mean "copy the corresponding 
  2881. Xpixel to the destination" while "zero" mask bits mean "leave this 
  2882. Xdestination pixel alone". In other words, "zero" bits designate transparent 
  2883. Xpixels.
  2884. X
  2885. XThe rows of the different bitplanes and mask are interleaved in the 
  2886. Xfile (see below). This localizes all the information pertinent to 
  2887. Xeach scan line. It makes it much easier to transform the data while 
  2888. Xreading it to adjust the image size or depth. It also makes it possible 
  2889. Xto scroll a big image by swapping rows directly from the file without 
  2890. Xrandom-accessing to all the bitplanes.
  2891. X
  2892. XBODY
  2893. X
  2894. XThe source raster  is stored in a "BODY" chunk. This one chunk holds 
  2895. Xall bitplanes and the optional mask, interleaved by row.
  2896. X
  2897. XThe BitMapHeader, in a BMHD property chunk, specifies the raster's 
  2898. Xdimensions w, h, and nPlanes. It also holds the masking field which 
  2899. Xindicates if there is a mask plane and the compression field which 
  2900. Xindicates the compression algorithm used. This information is needed 
  2901. Xto interpret the BODY chunk, so the BMHD chunk must appear first. 
  2902. XWhile reading an ILBM's BODY, a program may convert the image to another 
  2903. Xsize by filling (with transparentColor) or clipping.
  2904. X
  2905. XThe BODY's content is a concatenation of scan lines. Each scan line 
  2906. Xis a concatenation of one row of data from each plane in order 0 through 
  2907. XnPlanes-1 followed by one row from the mask (if masking = hasMask 
  2908. X). If the BitMapHeader field compression is cmpNone, all h rows are 
  2909. Xexactly Ceiling(w/16) words wide. Otherwise, every row is compressed 
  2910. Xaccording to the specified algorithm and their stored widths depend 
  2911. Xon the data compression.
  2912. X
  2913. XReader programs that require fewer bitplanes than appear in a particular 
  2914. XILBM file can combine planes or drop the high-order (later) planes. 
  2915. XSimilarly, they may add bitplanes and/or discard the mask plane.
  2916. X
  2917. XDo not compress across rows and don't forget to compress the mask 
  2918. Xjust like the bitplanes. Remember to pad any BODY chunk that contains 
  2919. Xan odd number of bytes.
  2920. X4. Nonstandard Data Chunk
  2921. X
  2922. XThe following data chunk was defined after various programs began 
  2923. Xusing FORM ILBM so it's a "nonstandard" chunk. That means there's 
  2924. Xsome slight chance of name collisions.
  2925. X
  2926. XCRNG
  2927. X
  2928. XA "CRNG" chunk contains "color register range" information. It's used 
  2929. Xby Electronic Arts' Deluxe Paint program to identify a contiguous 
  2930. Xrange of color registers for a "shade range" and color cycling. There 
  2931. Xcan be zero or more CRNG chunks in an ILBM, but all should appear 
  2932. Xbefore the BODY chunk. Deluxe Paint normally writes 4 CRNG chunks 
  2933. Xin an ILBM when the user asks it to "Save Picture".
  2934. X
  2935. Xtypedef struct {
  2936. X    WORD  pad1;    /* reserved for future use; store 0 here    */
  2937. X    WORD  rate;    /* color cycle rate    */
  2938. X    WORD  active;    /* nonzero means cycle the colors    */
  2939. X    UBYTE low, high; /* lower and upper color registers selected    */
  2940. X    } CRange;
  2941. X
  2942. XThe fields low and high indicate the range of color registers (color 
  2943. Xnumbers) selected by this CRange.
  2944. X
  2945. XThe field active indicates whether color cycling is on or off. Zero 
  2946. Xmeans off.
  2947. X
  2948. XThe field rate determines the speed at which the colors will step 
  2949. Xwhen color cycling is on. The units are such that a rate of 60 steps 
  2950. Xper second is represented as 214 = 16384. Slower rates can be obtained 
  2951. Xby linear scaling: for 30 steps/second, rate = 8192; for 1 step/second, 
  2952. Xrate = 16384/60 E 273.
  2953. X
  2954. XCCRT
  2955. X
  2956. XCommodore's Graphicraft program uses a similar chunk "CCRT" (for Color 
  2957. XCyling Range and Timing). This chunk contains a CycleInfo structure.
  2958. X
  2959. Xtypedef struct {
  2960. X    WORD  direction; /* 0 = don't cycle. 1 = cycle forwards (1, 2, 3).
  2961. X               * -1 = cycle backwards (3, 2, 1)    */
  2962. X    UBYTE start, end;  /* lower and upper color registers selected    */
  2963. X    LONG  seconds;       /* # seconds between changing colors    */
  2964. X    LONG  microseconds;    /* # microseconds between changing colors */ 
  2965. X    WORD  pad;        /* reserved for future use; store 0 here  */ 
  2966. X    } CycleInfo;
  2967. X
  2968. XThis is pretty similar to a CRNG chunk. A program would probably only 
  2969. Xuse one of these two methods of expressing color cycle data. You could 
  2970. Xwrite out both if you want to communicate this information to both 
  2971. XDeluxe Paint and Graphicraft.
  2972. X
  2973. XA CCRT chunk expresses the color cycling rate as a number of seconds 
  2974. Xplus a number of microseconds.
  2975. X
  2976. X
  2977. X
  2978. XAppendix A. ILBM Regular Expression
  2979. X
  2980. XHere's a regular expression summary of the FORM ILBM syntax. This 
  2981. Xcould be an IFF file or a part of one.
  2982. X
  2983. XILBM ::= "FORM" #{    "ILBM" BMHD [CMAP] [GRAB] [DEST] [SPRT] [CAMG]
  2984. X    CRNG* CCRT* [BODY]    }
  2985. X
  2986. XBMHD ::= "BMHD" #{    BitMapHeader    }
  2987. XCMAP ::= "CMAP" #{    (red green blue)*    } [0]
  2988. XGRAB ::= "GRAB" #{    Point2D    }
  2989. XDEST ::= "DEST" #{    DestMerge    }
  2990. XSPRT ::= "SPRT" #{    SpritePrecendence    }
  2991. XCAMG ::= "CAMG" #{    LONG    }
  2992. X
  2993. XCRNG ::= "CRNG" #{    CRange    }
  2994. XCCRT ::= "CCRT" #{    CycleInfo    }
  2995. XBODY ::= "BODY" #{    UBYTE*    } [0]
  2996. X
  2997. XThe token "#" represents a ckSize LONG count of the following {braced} 
  2998. Xdata bytes. E.g. a BMHD's "#" should equal sizeof(BitMapHeader). Literal 
  2999. Xstrings are shown in "quotes", [square bracket items] are optional, 
  3000. Xand "*" means 0 or more repetitions. A sometimes-needed pad byte is 
  3001. Xshown as "[0]".
  3002. X
  3003. XThe property chunks (BMHD, CMAP, GRAB, DEST, SPRT, and CAMG) and any 
  3004. XCRNG and CCRT data chunks may actually be in any order but all must 
  3005. Xappear before the BODY chunk since ILBM readers usually stop as soon 
  3006. Xas they read the BODY. If any of the 6 property chunks are missing, 
  3007. Xdefault values are "inherited" from any shared properties (if the 
  3008. XILBM appears inside an IFF LIST with PROPs) or from the reader program's 
  3009. Xdefaults. If any property appears more than once, the last occurrence 
  3010. Xbefore the BODY is the one that counts since that's the one that modifies 
  3011. Xthe BODY.
  3012. X
  3013. X
  3014. X
  3015. XAppendix B. ILBM Box Diagram
  3016. X
  3017. XHere's a box diagram for a simple example: an uncompressed image 320 
  3018. Xx 200 pixels x 3 bitplanes. The text to the right of the diagram shows 
  3019. Xthe outline that would be printed by the IFFCheck utility program 
  3020. Xfor this particular file.
  3021. X
  3022. X        +-----------------------------------+
  3023. X        |'FORM'         24070               |   FORM 24070 IBLM
  3024. X        +-----------------------------------+
  3025. X        |'ILBM'                             |
  3026. X        +-----------------------------------+
  3027. X        | +-------------------------------+ |
  3028. X        | | 'BMHD'      20                | |   .BMHD  20
  3029. X        | | 320, 200, 0, 0, 3, 0, 0, ...  | |
  3030. X        | + ------------------------------+ |
  3031. X        | | 'CMAP'      21                | |   .CMAP  21
  3032. X        | | 0, 0, 0; 32, 0, 0; 64,0,0; .. | |
  3033. X        | +-------------------------------+ |
  3034. X        | 0                                 |
  3035. X        +-----------------------------------+
  3036. X        |'BODY'         24000               |   .BODY 24000
  3037. X        |0, 0, 0, ...                       |
  3038. X        +-----------------------------------+
  3039. X
  3040. X
  3041. X
  3042. XThe "0" after the CMAP chunk is a pad byte.
  3043. X
  3044. X
  3045. X
  3046. XAppendix C. ByteRun1 Run Encoding
  3047. X
  3048. XThe run encoding scheme byteRun1 is best described by psuedo code 
  3049. Xfor the decoder Unpacker (called UnPackBits in the Macintosh* toolbox):
  3050. X
  3051. XUnPacker:
  3052. X    LOOP until produced the desired number of bytes
  3053. X        Read the next source byte into n
  3054. X        SELECT n FROM
  3055. X            [0..127]    => copy the next n+1 bytes literally
  3056. X            [-1..-127]    => replicate the next byte -n+1 times
  3057. X            -128    => noop
  3058. X            ENDCASE;
  3059. X        ENDLOOP;
  3060. X
  3061. XIn the inverse routine Packer, it's best to encode a 2 byte repeat 
  3062. Xrun as a replicate run except when preceded and followed by a literal 
  3063. Xrun, in which case it's best to merge the three into one literal run. 
  3064. XAlways encode 3 byte repeats as replicate runs.
  3065. X
  3066. XRemember that each row of each scan line of a raster is separately 
  3067. Xpacked.
  3068. X
  3069. X
  3070. X
  3071. XAppendix D. Standards Committee
  3072. X
  3073. XThe following people contributed to the design of this FORM ILBM standard:
  3074. X
  3075. XBob "Kodiak" Burns, Commodore-Amiga
  3076. XR. J. Mical, Commodore-Amiga
  3077. XJerry Morrison, Electronic Arts
  3078. XGreg Riker, Electronic Arts
  3079. XSteve Shaw, Electronic Arts
  3080. XDan Silva, Electronic Arts
  3081. XBarry Walsh, Commodore-Amiga
  3082. //END
  3083. echo x - smus
  3084. sed 's/^X//' > smus << '//END'
  3085. X"SMUS" IFF Simple Musical Score
  3086. X
  3087. XDate:    February 5, 1986
  3088. XFrom:    Jerry Morrison, Electronic Arts
  3089. XStatus:    Adopted
  3090. X
  3091. X1. Introduction
  3092. X
  3093. XThis is a reference manual for the data interchange format "SMUS", 
  3094. Xwhich stands for Simple MUsical Score. "EA IFF 85" is Electronic Arts' 
  3095. Xstandard for interchange format files. A FORM (or "data section") 
  3096. Xsuch as FORM SMUS can be an IFF file or a part of one. [See "EA IFF 
  3097. X85" Electronic Arts Interchange File Format.]
  3098. X
  3099. XSMUS is a practical data format for uses like moving limited scores 
  3100. Xbetween programs and storing theme songs for game programs. The format 
  3101. Xshould be geared for easy read-in and playback. So FORM SMUS uses 
  3102. Xthe compact time encoding of Common Music Notation (half notes, dotted 
  3103. Xquarter rests, etc.). The SMUS format should also be structurally 
  3104. Xsimple. So it has no provisions for fancy notational information needed 
  3105. Xby graphical score editors or the more general timing (overlapping 
  3106. Xnotes, etc.) and continuous data (pitch bends, etc.) needed by 
  3107. Xperformance-oriented MIDI recorders and sequencers.
  3108. X
  3109. XA SMUS score can say which "instruments" are supposed play which notes. 
  3110. XBut the score is independent of whatever output device and driver 
  3111. Xsoftware is used to perform the notes. The score can contain device- 
  3112. Xand driver-dependent instrument data, but this is just a cache. As 
  3113. Xlong as a SMUS file stays in one environment, the embedded instrument 
  3114. Xdata is very convenient. When you move a SMUS file between programs 
  3115. Xor hardware configurations, the contents of this cache usually become 
  3116. Xuseless.
  3117. X
  3118. XLike all IFF formats, SMUS is a filed or "archive" format. It is completely 
  3119. Xindependent of score representations in working memory, editing operations, 
  3120. Xuser interface, display graphics, computation hardware, and sound 
  3121. Xhardware. Like all IFF formats, SMUS is extensible.
  3122. X
  3123. XSMUS is not an end-all musical score format. Other formats may be 
  3124. Xmore appropriate for certain uses. (We'd like to design an general-use 
  3125. XIFF score format "GSCR". FORM GSCR would encode fancy notational data 
  3126. Xand performance data. There would be a SMUS to/from GSCR converter.)
  3127. X
  3128. XSection 2 gives important background information. Section 3 details 
  3129. Xthe SMUS components by defining the required property score header 
  3130. X"SHDR", the optional text properties name "NAME", copyright "(c) ", 
  3131. Xand author "AUTH", optional text annotation "ANNO", the optional instrument 
  3132. Xspecifier "INS1", and the track data chunk "TRAK". Section 4 defines 
  3133. Xsome chunks for particular programs to store private information. 
  3134. XThese are "standard" chunks; specialized chunks for future needs can 
  3135. Xbe added later. Appendix A is a quick-reference summary. Appendix 
  3136. XB is an example box diagram. Appendix C names the committee responsible 
  3137. Xfor this standard.
  3138. X
  3139. XUpdate: This standard has been revised since the draft versions. The 
  3140. X"INST" chunk type was revised to form the "INS1" chunk type. Also, 
  3141. Xseveral SEvent types and a few text chunk types have been added.
  3142. X
  3143. XNote: This is a MacWrite[tm] 4.5 document. If you strip it down to a 
  3144. Xtext file, you'll lose pictures, significant formatting information 
  3145. Xlike superscripts, and characters like ")". Don't do it.  
  3146. X
  3147. X
  3148. X  ----------------------------------------------------------------
  3149. X  |(Sorry, EA. We had to strip it down for ease of distribution, |
  3150. X  |  but we did convert pictures to text-form and where we could |
  3151. X  |  not do that, we provided ILBM illustrations that people     |
  3152. X  |  could actually show using the standard "showilbm" program)  |
  3153. X  ----------------------------------------------------------------
  3154. X
  3155. X
  3156. XReferences:
  3157. X
  3158. X"EA IFF 85" Standard for Interchange Format Files describes the underlying 
  3159. Xconventions for all IFF files.
  3160. X
  3161. X"8SVX" IFF 8-Bit Sampled Voice documents a data format for sampled 
  3162. Xinstruments.
  3163. X
  3164. XElectronic Arts[tm] is a trademark of Electronic Arts.
  3165. X
  3166. XMIDI: Musical Instrument Digital Interface Specification 1.0, International 
  3167. XMIDI Association, 1983.
  3168. X
  3169. XMacWrite[tm] is a trademark of Apple Computer, Inc.
  3170. X
  3171. XSSSP: See various articles on Structured Sound Synthesis Project in 
  3172. XFoundations of Computer Music.
  3173. X
  3174. X
  3175. X
  3176. X
  3177. X2. Background
  3178. X
  3179. XHere's some background information on score representation in general 
  3180. Xand design choices for SMUS.
  3181. X
  3182. XFirst, we'll borrow some terminology from the Structured Sound Synthesis 
  3183. XProject. [See the SSSP reference.] A "musical note" is one kind of 
  3184. Xscheduled event. It's properties include an event duration, an event 
  3185. Xdelay, and a timbre object. Theevent duration tells the scheduler 
  3186. Xhow long the note should last. The event delay tells how long after 
  3187. Xstarting this note to wait before starting the next event. The timbre 
  3188. Xobject selects sound driver data for the note; an "instrument" or 
  3189. X"timbre". A "rest" is a sort of a null event. Its only property is 
  3190. Xan event delay.
  3191. X
  3192. XClassical Event Durations
  3193. X
  3194. XSMUS is geared for "classical" scores, not free-form performances. 
  3195. XSo its event durations are classical (whole note, dotted quarter rest, 
  3196. Xetc.). It can tie notes together to build a "note event" with an unusual 
  3197. Xevent duration.
  3198. X
  3199. XThe set of useful classical durations is very small. So SMUS needs 
  3200. Xonly a handful of bits to encode an event duration. This is very compact. 
  3201. XIt's also very easy to display in Common Music Notation (CMN).
  3202. X
  3203. XTracks
  3204. X
  3205. XThe events in a SMUS score are grouped into parallel "tracks". Each 
  3206. Xtrack is a linear stream of events.
  3207. X
  3208. XWhy use tracks? Tracks serve 4 functions:
  3209. X
  3210. X1.    Tracks make it possible to encode event delays very compactly. 
  3211. XA "classical" score has chorded notes and sequential notes; no overlapping 
  3212. Xnotes. That is, each event begins either simultaneous with or immediately 
  3213. Xfollowing the previous event in that track. So each event delay is 
  3214. Xeither 0 or the same as the event's duration. This binary distinction 
  3215. Xrequires only one bit of storage.
  3216. X
  3217. X2.    Tracks represent the "voice tracks" in Common Music Notation. 
  3218. XCMN organizes a score in parallel staves, with one or two "voice tracks" 
  3219. Xper staff. So one or two SMUS tracks represents a CMN staff.
  3220. X
  3221. X3.    Tracks are a good match to available sound hardware. We can 
  3222. Xuse "instrument settings" in a track to store the timbre assignments 
  3223. Xfor that track's notes. The instrument setting may change over the 
  3224. Xtrack.
  3225. X
  3226. X    Furthermore, tracks can help to allocate notes among available 
  3227. Xoutput channels or performance devices or tape recorder "tracks". 
  3228. XTracks can also help to adapt polyphonic data to monophonic output 
  3229. Xchannels.
  3230. X
  3231. X4.    Tracks are a good match to simple sound software. Each track 
  3232. Xis a place to hold state settings like "dynamic mark pp ", "time signature 
  3233. X3/4", "mute this track", etc., just as it's a context for instrument 
  3234. Xsettings. This is a lot like a text stream with running "font" and 
  3235. X"face" properties (attributes). Running state is usually more compact 
  3236. Xthan, say, storing an instrument setting in every note event. It's 
  3237. Xalso a useful way to organize "attributes" of notes. With "running 
  3238. Xtrack state" we can define new note attributes in an upward- and 
  3239. Xbackward-compatible way.
  3240. X
  3241. X    Running track state can be expanded (run decoded) while loading 
  3242. Xa track into memory or while playing the track. The runtime track 
  3243. Xstate must be reinitialized every time the score is played.
  3244. X
  3245. XSeparated vs. interleaved tracks. Multi-track data could be stored 
  3246. Xeither as separate event streams or interleaved into one stream. To 
  3247. Xinterleave the streams, each event has to carry a "track number" attribute.
  3248. X
  3249. XIf we were designing an editable score format, we might interleave 
  3250. Xthe streams so that nearby events are stored nearby. This helps when 
  3251. Xsearching the data, especially if you can't fit the entire score into 
  3252. Xmemory at once. But it takes extra storage for the track numbers and 
  3253. Xmay take extra work to manipulate the interleaved tracks.
  3254. X
  3255. XThe musical score format FORM SMUS is intended for simple loading 
  3256. Xand playback of small scores that fit entirely in main memory. So 
  3257. Xwe chose to store its tracks separately.
  3258. X
  3259. XThere can be up to 255 tracks in a FORM SMUS. Each track is stored 
  3260. Xas a TRAK chunk. The count of tracks (the number of TRAK chunks) is 
  3261. Xrecorded in the SHDR chunk at the beginning of the FORM SMUS. The 
  3262. XTRAK chunks appear in numerical order 1, 2, 3, .... This is also priority 
  3263. Xorder, most important track first. A player program that can handle 
  3264. Xup to N parallel tracks should read the first N tracks and ignore 
  3265. Xany others.
  3266. X
  3267. XThe different tracks in a score may have different lengths. This is 
  3268. Xtrue both of storage length and of playback duration.
  3269. X
  3270. XInstrument Registers
  3271. X
  3272. XInstrument reference. In SSSP, each note event points to a "timbre 
  3273. Xobject" which supplies the "instrument" (the sound driver data) for 
  3274. Xthat note. FORM SMUS stores these pointers as a "current instrument 
  3275. Xsetting" for each track. It's just a run encoded version of the same 
  3276. Xinformation. SSSP uses a symbol table to hold all the pointers to 
  3277. X"timbre object". SMUS uses INS1 chunks for the same purpose. They 
  3278. Xname the score's instruments.
  3279. X
  3280. XThe actual instrument data to use depends on the playback environment, 
  3281. Xbut we want the score to be independent of environment. Different 
  3282. Xplayback environments have different audio output hardware and different 
  3283. Xsound driver software. And there are channel allocation issues like 
  3284. Xhow many output channels there are, which ones are polyphonic, and 
  3285. Xwhich I/O ports they're connected to. If you use MIDI to control the 
  3286. Xinstruments, you get into issues of what kind of device is listening 
  3287. Xto each MIDI channel and what each of its preset sounds like. If you 
  3288. Xuse computer-based instruments, you need driver-specific data like 
  3289. Xwaveform tables and oscillator parameters.
  3290. X
  3291. XWe just want to put some orchestration in the score. If the score 
  3292. Xwants a "piano", we let the playback program to find a "piano".
  3293. X
  3294. XInstrument reference by name. A reference from a SMUS score to actual 
  3295. Xinstrument data is normally by name. The score simply names the instrument, 
  3296. Xfor instance "tubular bells". It's up to the player program to find 
  3297. Xsuitable instrument data for its output devices. (More on locating 
  3298. Xinstruments below.)
  3299. X
  3300. XInstrument reference by MIDI channel and preset. A SMUS score can 
  3301. Xalso ask for a specific MIDI channel number and preset number. MIDI 
  3302. Xprograms may honor these specific requests. But these channel allocations 
  3303. Xcan become obsolete or the score may be played without MIDI hardware. 
  3304. XIn such cases, the player program should fall back to instrument reference 
  3305. Xby name.
  3306. X
  3307. XInstrument reference via instrument register. Each reference from 
  3308. Xa SMUS track to an instrument is via an "instrument register". Each 
  3309. Xtrack selects an instrument register which in turn points to the specific 
  3310. Xinstrument data.
  3311. X
  3312. XEach score has an array of instrument registers. Each track has a 
  3313. X"current instrument setting", which is simply an index number into 
  3314. Xthis array. This is like setting a raster image's pixel to a specific 
  3315. Xcolor number (a reference to a color value through a "color register") 
  3316. Xor setting a text character to a specific font number (a reference 
  3317. Xto a font through a "font register"). This is diagrammed below.
  3318. X
  3319. X
  3320. X Track 1  |Set Inst 2| Note | Note | Set Inst 1 | Note | Note | Note |... 
  3321. X        |              |
  3322. X  +-------------+              |
  3323. X  |  +------------------------------------+
  3324. X  |  |           +--------------------------------------------------------+
  3325. X  |  +-------->|"piano"  ---------------> (internal piano data)         |
  3326. X  +----------->|"guitar" ---------------> (internal guitar data)    |
  3327. X           |"Spanish guitar" -------> (internal Spanish guitar data)|
  3328. X     +-------->|"bass drum" ------------> (internal bass drum data)    |
  3329. X     |           +--------------------------------------------------------+
  3330. X     |
  3331. X     +---------+
  3332. X           |
  3333. X Track 2  |Set Inst 4| Note | Note | Note | Note | Note | Note | Note |... 
  3334. X
  3335. X
  3336. X
  3337. XLocating instrument data by name. "INS1" chunks in a SMUS score name 
  3338. Xthe instruments to use for that score. The player program uses these 
  3339. Xnames to locate instrument data.
  3340. X
  3341. XTo locate instrument data, the player performs these steps:
  3342. X
  3343. XFor each instrument register, check for a suitable instrument with 
  3344. Xthe right name.  "Suitable" means usable with an available output 
  3345. Xdevice and driver.  {Use case independent name comparisons.}
  3346. X
  3347. X1.    Initialize the instrument register to point to a built-in default 
  3348. X    instrument.  {Every player program must have default instruments. 
  3349. X    Simple programs stop here. For fancier programs, the default 
  3350. X    instruments are a backstop in case the search fails.}
  3351. X
  3352. X2.    Check any instrument FORMs embedded in the FORM SMUS. (This 
  3353. X    is an "instrument cache".)
  3354. X
  3355. X3.    Else check the default instruments.
  3356. X
  3357. X4.    Else search the local "instrument library". (The library might 
  3358. X    simply be a disk directory.)
  3359. X
  3360. X5.    If all else fails, display the desired instrument name and 
  3361. X    ask the user to pick an available one.
  3362. X
  3363. XThis algorithm can be implemented to varying degrees of fanciness. 
  3364. XIt's ok to stop searching after step 1, 2, 3, or 4. If exact instrument 
  3365. Xname matches fail, it's ok to try approximate matches. E.g. search 
  3366. Xfor any kind of "guitar" if you can't find a "Spanish guitar". In 
  3367. Xany case, a player only has to search for instruments while loading 
  3368. Xa score.
  3369. X
  3370. XWhen the embedded instruments are suitable, they save the program 
  3371. Xfrom asking the user to insert the "right" disk in a drive and searching 
  3372. Xthat disk for the "right" instrument. But it's just a cache. In practice, 
  3373. Xwe rarely move scores between environments so the cache often works. 
  3374. XWhen the score is moved, embedded instruments must be discarded (a 
  3375. Xcache miss) and other instrument data used.
  3376. X
  3377. XBe careful to distinguish an instrument's name from its filenameQthe 
  3378. Xcontents name vs. container name. A musical instrument FORM should 
  3379. Xcontain a NAME chunk that says what instrument it really is. Its filename, 
  3380. Xon the other hand, is a handle used to locate the FORM. Filenames 
  3381. Xare affected by external factors like drives, directories, and filename 
  3382. Xcharacter and length limits. Instrument names are not.
  3383. X
  3384. XIssue: Consider instrument naming conventions for consistency. Consider 
  3385. Xa naming convention that aids approximate matches. E.g. we could accept 
  3386. X"guitar, bass1" if we didn't find "guitar, bass". Failing that, we 
  3387. Xcould accept "guitar" or any name starting with "guitar".
  3388. X
  3389. XSet instrument events. If the player implements the set-instrument 
  3390. Xscore event, each track can change instrument numbers while playing. 
  3391. XThat is, it can switch between the loaded instruments.
  3392. X
  3393. XInitial instrument settings. Each time a score is played, every tracks' 
  3394. Xrunning state information must be initialized. Specifically, each 
  3395. Xtrack's instrument number should be initialized to its track number. 
  3396. XTrack 1 to instrument 1, etc. It's as if each track began with a 
  3397. Xset-instrument event.
  3398. X
  3399. XIn this way, programs that don't implement the set-instrument event 
  3400. Xstill assign an instrument to each track. The INS1 chunks imply these 
  3401. Xinitial instrument settings.
  3402. X
  3403. XMIDI Instruments
  3404. X
  3405. XAs mentioned above, A SMUS score can also ask for MIDI instruments. 
  3406. XThis is done by putting the MIDI channel and preset numbers in an 
  3407. XINS1 chunk with the instrument name. Some programs will honor these 
  3408. Xrequests while others will just find instruments by name.
  3409. X
  3410. XMIDI Recorder and sequencer programs may simply transcribe the MIDI 
  3411. Xchannel and preset commands in a recording session. For this purpose, 
  3412. Xset-MIDI-channel and set-MIDI-preset events can be embedded in a SMUS 
  3413. Xscore's tracks. Most programs should ignore these events. An editor 
  3414. Xprogram that wants to exchange scores with such programs should recognize 
  3415. Xthese events. It should let the user change them to the more general 
  3416. Xset-instrument events.
  3417. X
  3418. X
  3419. X
  3420. X3. Standard Data and Property Chunks
  3421. X
  3422. XA FORM SMUS contains a required property "SHDR" followed by any number 
  3423. Xof parallel "track" data chunks "TRAK". Optional property chunks such 
  3424. Xas "NAME", copyright "(c) ", and instrument reference "INS1" may also 
  3425. Xappear. Any of the properties may be shared over a LIST of FORMs SMUS 
  3426. Xby putting them in a PROP SMUS. [See the IFF reference.]
  3427. X
  3428. XRequired Property SHDR
  3429. X
  3430. XThe required property "SHDR" holds an SScoreHeader as defined in these 
  3431. XC declarations and following documentation. An SHDR specifies global 
  3432. Xinformation for the score. It must appear before the TRAKs in a FORM 
  3433. XSMUS.
  3434. X
  3435. X#define ID_SMUS MakeID('S', 'M', 'U', 'S')
  3436. X#define ID_SHDR MakeID('S', 'H', 'D', 'R')
  3437. X
  3438. Xtypedef struct {
  3439. X    UWORD tempo;    /* tempo, 128ths quarter note/minute    */
  3440. X    UBYTE volume;    /* overall playback volume 0 through 127    */
  3441. X    UBYTE ctTrack;    /* count of tracks in the score    */
  3442. X    } SScoreHeader;
  3443. X
  3444. X[Implementation details. In the C struct definitions in this memo, 
  3445. Xfields are filed in the order shown. A UBYTE field is packed into 
  3446. Xan 8-bit byte. Programs should set all "pad" fields to 0. MakeID is 
  3447. Xa C macro defined in the main IFF document and in the source file 
  3448. XIFF.h.]
  3449. X
  3450. XThe field tempo gives the nominal tempo for all tracks in the score. 
  3451. XIt is expressed in 128ths of a quarter note per minute, i.e. 1 represents 
  3452. X1 quarter note per 128 minutes while 12800 represents 100 quarter 
  3453. Xnotes per minute. You may think of this as a fixed point fraction 
  3454. Xwith a 9-bit integer part and a 7-bit fractional part (to the right 
  3455. Xof the point). A course-tempoed program may simply shift tempo right 
  3456. Xby 7 bits to get a whole number of quarter notes per minute. The tempo 
  3457. Xfield can store tempi in the range 0 up to 512. The playback program 
  3458. Xmay adjust this tempo, perhaps under user control.
  3459. X
  3460. XActually, this global tempo could actually be just an initial tempo 
  3461. Xif there are any "set tempo" SEvents inside the score (see TRAK, below). 
  3462. XOr the global tempo could be scaled by "scale tempo" SEvents inside 
  3463. Xthe score. These are potential extensions that can safely be ignored 
  3464. Xby current programs. [See More SEvents To Be Defined, below.]
  3465. X
  3466. XThe field volume gives an overall nominal playback volume for all 
  3467. Xtracks in the score. The range of volume values 0 through 127 is like 
  3468. Xa MIDI key velocity value. The playback program may adjust this volume, 
  3469. Xperhaps under direction of a user "volume control".
  3470. X
  3471. XActually, this global volume level could be scaled by dynamic-mark 
  3472. XSEvents inside the score (see TRAK, below).
  3473. X
  3474. XThe field ctTrack holds the count of tracks, i.e. the number of TRAK 
  3475. Xchunks in the FORM SMUS (see below). This information helps the reader 
  3476. Xprepare for the following data.
  3477. X
  3478. XA playback program will typically load the score and call a driver 
  3479. Xroutine PlayScore(tracks, tempo, volume), supplying the tempo and 
  3480. Xvolume from the SHDR chunk.
  3481. X
  3482. XOptional Text Chunks NAME, (c), AUTH, ANNO
  3483. X
  3484. XSeveral text chunks may be included in a FORM SMUS to keep ancillary 
  3485. Xinformation.
  3486. X
  3487. XThe optional property "NAME" names the musical score, for instance 
  3488. X"Fugue in C".
  3489. X
  3490. XThe optional property "(c)J" holds a copyright notice for the score. 
  3491. XThe chunk ID "(c)J" serves the function of the copyright characters 
  3492. X")J". E.g. a "(c)J" chunk containing "1986 Electronic Arts" means 
  3493. X") 1986 Electronic Arts".
  3494. X
  3495. XThe optional property "AUTH" holds the name of the score's author.
  3496. X
  3497. XThe chunk types "NAME", "(c) ", and "AUTH" are property chunks. Putting 
  3498. Xmore than one NAME (or other) property in a FORM is redundant. Just 
  3499. Xthe last NAME counts. A property should be shorter than 256 characters. 
  3500. XProperties can appear in a PROP SMUS to share them over a LIST of 
  3501. XFORMs SMUS.
  3502. X
  3503. XThe optional data chunk "ANNO" holds any text annotations typed in 
  3504. Xby the author.
  3505. X
  3506. XAn ANNO chunk is not a property chunk, so you can put more than one 
  3507. Xin a FORM SMUS. You can make ANNO chunks any length up to 231 - 1 
  3508. Xcharacters, but 32767 is a practical limit. Since they're not properties, 
  3509. XANNO chunks don't belong in a PROP SMUS. That means they can't be 
  3510. Xshared over a LIST of FORMs SMUS.
  3511. X
  3512. XSyntactically, each of these chunks contains an array of 8-bit ASCII 
  3513. Xcharacters in the range R S (SP, hex 20) through R~S (tilde, hex 7F), 
  3514. Xjust like a standard "TEXT" chunk. [See "Strings, String Chunks, and 
  3515. XString Properties" in "EA IFF 85" Electronic Arts Interchange File 
  3516. XFormat.] The chunk's ckSize field holds the count of characters.
  3517. X
  3518. X#define ID_NAME MakeID('N', 'A', 'M', 'E')
  3519. X/* NAME chunk contains a CHAR[], the musical score's name.    */
  3520. X
  3521. X#define ID_Copyright MakeID('(', 'c', ')', ' ')
  3522. X/* "(c) " chunk contains a CHAR[], the FORM's copyright notice.    */
  3523. X
  3524. X#define ID_AUTH MakeID('A', 'U', 'T', 'H')
  3525. X/* AUTH chunk contains a CHAR[], the name of the score's author.    */
  3526. X
  3527. X#define ID_ANNO MakeID('A', 'N', 'N', 'O')
  3528. X/* ANNO chunk contains a CHAR[], author's text annotations.    */
  3529. X
  3530. XRemember to store a 0 pad byte after any odd-length chunk.
  3531. X
  3532. XOptional Property INS1
  3533. X
  3534. XThe "INS1" chunks in a FORM SMUS identify the instruments to use for 
  3535. Xthis score. A program can ignore INS1 chunks and stick with its built-in 
  3536. Xdefault instrument assignments. Or it can use them to locate instrument 
  3537. Xdata. [See "Instrument Registers" in section 2, above.]
  3538. X
  3539. X#define ID_INS1 MakeID('I', 'N', 'S', '1')
  3540. X
  3541. X/* Values for the RefInstrument field "type".    */
  3542. X#define INS1_Name  0    /* just use the name; ignore data1, data2    */
  3543. X#define INS1_MIDI  1    /* <<data1, data2> = MIDI <<channel, preset>    */
  3544. X
  3545. Xtypedef struct {
  3546. X    UBYTE register;    /* set this instrument register number    */
  3547. X    UBYTE type;    /* instrument reference type    */
  3548. X    UBYTE data1, data2;    /* depends on the "type" field    */
  3549. X    CHAR  name[];    /* instrument name    */
  3550. X    } RefInstrument;
  3551. X
  3552. XAn INS1 chunk names the instrument for instrument register number 
  3553. Xregister. The register field can range from 0 through 255. In practice, 
  3554. Xmost scores will need only a few instrument registers.
  3555. X
  3556. XThe name field gives a text name for the instrument. The string length 
  3557. Xcan be determined from the ckSize of the INS1 chunk. The string is 
  3558. Xsimply an array of 8-bit ASCII characters in the range R S (SP, hex 
  3559. X20) through R~S (tilde, hex 7F).
  3560. X
  3561. XBesides the instrument name, an INS1 chunk has two data numbers to 
  3562. Xhelp locate an instrument. The use of these data numbers is controlled 
  3563. Xby the type field. A value type = INS1_Name means just find an instrument 
  3564. Xby name. In this case, data1 and data2 should just be set to 0. A 
  3565. Xvalue type = INS1_MIDI means look for an instrument on MIDI channel 
  3566. X# data1, preset # data2. Programs and computers without MIDI outputs 
  3567. Xwill just ignore the MIDI data. They'll always look for the named 
  3568. Xinstrument. Other values of the type field are reserved for future 
  3569. Xstandardization.
  3570. X
  3571. XSee section 2, above, for the algorithm for locating instrument data 
  3572. Xby name.
  3573. X
  3574. XObsolete Property INST
  3575. X
  3576. XThe chunk type "INST" is obsolete in SMUS. It was revised to form 
  3577. Xthe "INS1" chunk.
  3578. X
  3579. XData Chunk TRAK
  3580. X
  3581. XThe main contents of a score is stored in one or more TRAK chunks 
  3582. Xrepresenting parallel "tracks". One TRAK chunk per track.
  3583. X
  3584. XThe contents of a TRAK chunk is an array of 16-bit "events" such as 
  3585. X"note", "rest", and "set instrument". Events are really commands to 
  3586. Xa simple scheduler, stored in time order. The tracks can be polyphonic, 
  3587. Xthat is, they can contain chorded "note" events.
  3588. X
  3589. XEach event is stored as an "SEvent" record. ("SEvent" means "simple 
  3590. Xmusical event".) Each SEvent has an 8-bit type field called an "sID" 
  3591. Xand 8 bits of type-dependent data. This is like a machine language 
  3592. Xinstruction with an 8-bit opcode and an 8-bit operand.
  3593. X
  3594. XThis format is extensible since new event types can be defined in 
  3595. Xthe future. The "note" and "rest" events are the only ones that every 
  3596. Xprogram must understand. We will carefully design any new event types 
  3597. Xso that programs can safely skip over unrecognized events in a score.
  3598. X
  3599. XCaution: SID codes must be allocated by a central clearinghouse to 
  3600. Xavoid conflicts.
  3601. X
  3602. XHere are the C type definitions for TRAK and SEvent and the currently 
  3603. Xdefined sID values. Afterward are details on each SEvent.
  3604. X
  3605. X#define ID_TRAK MakeID('T', 'R', 'A', 'K')
  3606. X
  3607. X/* TRAK chunk contains an SEvent[].    */
  3608. X
  3609. X/* SEvent: Simple musical event.    */
  3610. Xtypedef struct {
  3611. X    UBYTE sID;    /* SEvent type code    */
  3612. X    UBYTE data;    /* sID-dependent data    */
  3613. X    } SEvent;
  3614. X
  3615. X/* SEvent type codes "sID".        */
  3616. X#define SID_FirstNote     0
  3617. X#define SID_LastNote    127    /* sIDs in the range SID_FirstNote through
  3618. X                  * SID_LastNote (sign bit = 0) are notes. The
  3619. X                  * sID is the MIDI tone number (pitch).    */
  3620. X#define SID_Rest        128    /* a rest (same data format as a note).    */
  3621. X
  3622. X#define SID_Instrument  129    /* set instrument number for this 
  3623. Xtrack.    */
  3624. X#define SID_TimeSig     130    /* set time signature for this track.    */
  3625. X#define SID_KeySig      131    /* set key signature for this track.    */
  3626. X#define SID_Dynamic     132    /* set volume for this track.    */
  3627. X#define SID_MIDI_Chnl   133    /* set MIDI channel number (sequencers)    */
  3628. X#define SID_MIDI_Preset 134    /* set MIDI preset number (sequencers)    */
  3629. X
  3630. X/* SID values 144 through 159: reserved for Instant Music SEvents.    */
  3631. X
  3632. X/* Remaining sID values up through 254: reserved for future
  3633. X * standardization.        */
  3634. X
  3635. X#define SID_Mark        255    /* sID reserved for an end-mark in RAM.    */
  3636. X
  3637. XNote and Rest SEvents
  3638. X
  3639. XThe note and rest SEvents SID_FirstNote through SID_Rest have the 
  3640. Xfollowing structure overlaid onto the SEvent structure:
  3641. X
  3642. Xtypedef struct {
  3643. X    UBYTE    tone;    /* MIDI tone number 0 to 127; 128 = rest    */
  3644. X    unsigned chord    :1,    /* 1 = a chorded note    */
  3645. X        tieOut   :1,    /* 1 = tied to the next note or chord    */
  3646. X        nTuplet  :2,    /* 0 = none, 1 = triplet, 2 = quintuplet,
  3647. X    * 3 = septuplet    */
  3648. X        dot      :1,    /* dotted note; multiply duration by 3/2    */
  3649. X        division :3;    /* basic note duration is 2-division: 0 = whole
  3650. X              * note, 1 = half note, 2 = quarter note, I 
  3651. X             * 7 = 128th note    */
  3652. X    } SNote;
  3653. X
  3654. X[Implementation details. Unsigned ":n" fields are packed into n bits 
  3655. Xin the order shown, most significant bit to least significant bit. 
  3656. XAn SNote fits into 16 bits like any other SEvent. Warning: Some compilers 
  3657. Xdon't implement bit-packed fields properly. E.g. Lattice 68000 C pads 
  3658. Xa group of bit fields out to a LONG, which would make SNote take 5-bytes! 
  3659. XIn that situation, use the bit-field constants defined below.]
  3660. X
  3661. XThe SNote structure describes one "note" or "rest" in a track. The 
  3662. Xfield SNote.tone, which is overlaid with the SEvent.sID field, indicates 
  3663. Xthe MIDI tone number (pitch) in the range 0 through 127. A value of 
  3664. X128 indicates a rest.
  3665. X
  3666. XThe fields nTuplet, dot, and division together give the duration of 
  3667. Xthe note or rest. The division gives the basic duration: whole note, 
  3668. Xhalf note, etc. The dot indicates if the note or rest is dotted. A 
  3669. Xdotted note is 3/2 as long as an undotted note. The value nTuplet 
  3670. X(0 through 3) tells if this note or rest is part of an N-tuplet of 
  3671. Xorder 1 (normal), 3, 5, or 7; an N-tuplet of order (2J*JnTupletJ+J1). 
  3672. XA triplet note is 2/3 as long as a normal note, while a quintuplet 
  3673. Xis 4/5 as long and a septuplet is 6/7 as long.
  3674. X
  3675. XPutting these three fields together, the duration of the note or rest 
  3676. Xis 2-division * {1, 3/2} * {1, 2/3, 4/5, 6/7}
  3677. X
  3678. XThese three fields are contiguous so you can easily convert to your 
  3679. Xlocal duration encoding by using the combined 6 bits as an index into 
  3680. Xa mapping table.
  3681. X
  3682. XThe field chord indicates if the note is chorded with the following 
  3683. Xnote (which is supposed to have the same duration). A group of notes 
  3684. Xmay be chorded together by setting the chord bit of all but the last 
  3685. Xone. (In the terminology of SSSP and GSCR, setting the chord bit to 
  3686. X1 makes the "entry delay" 0.) A monophonic-track player can simply 
  3687. Xignore any SNote event whose chord bit is set, either by discarding 
  3688. Xit when reading the track or by skipping it when playing the track.
  3689. X
  3690. XPrograms that create polyphonic tracks are expected to store the most 
  3691. Ximportant note of each chord last, which is the note with the 0 chord 
  3692. Xbit. This way, monophonic programs will play the most important note 
  3693. Xof the chord. The most important note might be the chord's root note 
  3694. Xor its melody note.
  3695. X
  3696. XIf the field tieOut is set, the note is tied to the following note 
  3697. Xin the track if the following note has the same pitch. A group of 
  3698. Xtied notes is played as a single note whose duration is the sum of 
  3699. Xthe component durations. Actually, the tie mechanism ties a group 
  3700. Xof one or more chorded notes to another group of one or more chorded 
  3701. Xnotes. Every note in a tied chord should have its tieOut bit set.
  3702. X
  3703. XOf course, the chord and tieOut fields don't apply to SID_Rest SEvents.
  3704. X
  3705. XPrograms should be robust enough to ignore an unresolved tie, i.e. 
  3706. Xa note whose tieOut bit is set but isn't followed by a note of the 
  3707. Xsame pitch. If that's true, monophonic-track programs can simply ignore 
  3708. Xchorded notes even in the presense of ties. That is, tied chords pose 
  3709. Xno extra problems.
  3710. X
  3711. XThe following diagram shows some combinations of notes and chords 
  3712. Xtied to notes and chords. The text below the staff has a column for 
  3713. Xeach SNote SEvent to show the pitch, chord bit, and tieOut bit.
  3714. X
  3715. X
  3716. X
  3717. X        (figure)
  3718. X
  3719. X
  3720. X
  3721. X
  3722. XIf you read the above track into a monophonic-track program, it'll 
  3723. Xstrip out the chorded notes and ignore unresolved ties. You'll end 
  3724. Xup with:
  3725. X
  3726. X
  3727. X
  3728. X        (figure)
  3729. X
  3730. X
  3731. X
  3732. X
  3733. XA rest event (sID = SID_Rest) has the same SEvent.data field as a 
  3734. Xnote. It tells the duration of the rest. The chord and tieOut fields 
  3735. Xof rest events are ignored.
  3736. X
  3737. XWithin a TRAK chunk, note and rest events appear in time order.
  3738. X
  3739. XInstead of the bit-packed structure SNote, it might be easier to assemble 
  3740. Xdata values by or-ing constants and to disassemble them by masking 
  3741. Xand shifting. In that case, use the following definitions.
  3742. X
  3743. X#define noteChord  (1<<<<7)    /* note is chorded to next note    */
  3744. X
  3745. X#define noteTieOut (1<<<<6)    /* tied to next note/chord    */
  3746. X
  3747. X#define noteNShift 4    /* shift count for nTuplet field    */
  3748. X#define noteN3     (1<<<<noteNShift)    /* note is a triplet    */
  3749. X#define noteN5     (2<<<<noteNShift)    /* note is a quintuplet    */
  3750. X#define noteN7     (3<<<<noteNShift)    /* note is a septuplet    */
  3751. X#define noteNMask  noteN7    /* bit mask for the nTuplet field    */
  3752. X
  3753. X#define noteDot    (1<<<<3)    /* note is dotted    */
  3754. X
  3755. X#define noteD1     0    /* whole note division    */
  3756. X#define noteD2     1    /* half note division    */
  3757. X#define noteD4     2    /* quarter note division    */
  3758. X#define noteD8     3     /* eighth note division    */
  3759. X#define noteD16    4     /* sixteenth note division    */
  3760. X#define noteD32    5     /* thirty-secondth note division    */
  3761. X#define noteD64    6     /* sixty-fourth note division    */
  3762. X#define noteD128   7     /* 1/128 note division    */
  3763. X#define noteDMask  noteD128    /* bit mask for the division field    */
  3764. X
  3765. X#define noteDurMask 0x3F    /* mask for combined duration fields    */
  3766. X
  3767. XNote: The remaining SEvent types are optional. A writer program doesn't 
  3768. Xhave to generate them. A reader program can safely ignore them.
  3769. X
  3770. XSet Instrument SEvent
  3771. X
  3772. XOne of the running state variables of every track is an instrument 
  3773. Xnumber. An instrument number is the array index of an "instrument 
  3774. Xregister", which in turn points to an instrument. (See "Instrument 
  3775. XRegisters", in section 2.) This is like a color number in a bitmap; 
  3776. Xa reference to a color through a "color register".
  3777. X
  3778. XThe initial setting for each track's instrument number is the track 
  3779. Xnumber. Track 1 is set to instrument 1, etc. Each time the score is 
  3780. Xplayed, every track's instrument number should be reset to the track 
  3781. Xnumber.
  3782. X
  3783. XThe SEvent SID_Instrument changes the instrument number for a track, 
  3784. Xthat is, which instrument plays the following notes. Its SEvent.data 
  3785. Xfield is an instrument register number in the range 0 through 255. 
  3786. XIf a program doesn't implement the SID_Instrument event, each track 
  3787. Xis fixed to one instrument.
  3788. X
  3789. XSet Time Signature SEvent
  3790. X
  3791. XThe SEvent SID_TimeSig sets the time signature for the track. A "time 
  3792. Xsignature" SEvent has the following structure overlaid on the SEvent 
  3793. Xstructure:
  3794. X
  3795. Xtypedef struct {
  3796. X    UBYTE    type;    /* = SID_TimeSig    */
  3797. X    unsigned timeNSig :5,    /* time sig. "numerator" is timeNSig + 1 */ 
  3798. X    timeDSig :3;    /* time sig. "denominator" is 2timeDSig: 
  3799. X             * 0 = whole note, 1 = half note, 2 = quarter      
  3800. X             * note, I 7 = 128th note    */
  3801. X    } STimeSig;
  3802. X
  3803. X[Implementation details. Unsigned ":n" fields are packed into n bits 
  3804. Xin the order shown, most significant bit to least significant bit. 
  3805. XAn STimeSig fits into 16 bits like any other SEvent. Warning: Some 
  3806. Xcompilers don't implement bit-packed fields properly. E.g. Lattice 
  3807. XC pads a group of bit fields out to a LONG, which would make an STimeSig 
  3808. Xtake 5-bytes! In that situation, use the bit-field constants defined 
  3809. Xbelow.]
  3810. X
  3811. XThe field type contains the value SID_TimeSig, indicating that this 
  3812. XSEvent is a "time signature" event. The field timeNSig indicates the 
  3813. Xtime signature "numerator" is timeNSig + 1, that is, 1 through 32 
  3814. Xbeats per measure. The field timeDSig indicates the time signature 
  3815. X"denominator" is 2timeDSig, that is each "beat" is a 2-timeDSig note 
  3816. X(see SNote division, above). So 4/4 time is expressed as timeNSig 
  3817. X= 3, timeDSig = 2.
  3818. X
  3819. XThe default time signature is 4/4 time.
  3820. X
  3821. XBeware that the time signature has no effect on the score's playback. 
  3822. XTempo is uniformly expressed in quarter notes per minute, independent 
  3823. Xof time signature. (Quarter notes per minute equals beats per minute 
  3824. Xonly if timeDSig = 2, n/4 time). Nonetheless, any program that has 
  3825. Xtime signatures should put them at the beginning of each TRAK when 
  3826. Xcreating a FORM SMUS because music editors need them.
  3827. X
  3828. XInstead of the bit-packed structure STimeSig, it might be easier to 
  3829. Xassemble data values by or-ing constants and to disassemble them by 
  3830. Xmasking and shifting. In that case, use the following definitions.
  3831. X
  3832. X#define timeNMask  0xF8    /* bit mask for the timeNSig field    */
  3833. X#define timeNShift 3    /* shift count for  timeNSig field    */
  3834. X
  3835. X#define timeDMask  0x07    /* bit mask for the timeDSig field    */
  3836. X
  3837. XKey Signature SEvent
  3838. X
  3839. XAn SEvent SID_KeySig sets the key signature for the track. Its data 
  3840. Xfield is a UBYTE number encoding a major key:
  3841. X
  3842. Xdata    key    music notation    data    key    music notation
  3843. XJ0    C maj
  3844. XJ1    G    #    J8    F    b
  3845. XJ2    D    ##    J9    Bb    bb
  3846. XJ3    A    ###    10    Eb    bbb
  3847. XJ4    E    ####    11    Ab    bbbb
  3848. XJ5    B    #####    12    Db    bbbbb
  3849. XJ6    F#    ######    13    Gb    bbbbbb
  3850. XJ7    C#    #######    14    Cb    bbbbbbb
  3851. X
  3852. XA SID_KeySig SEvent changes the key for the following notes in that 
  3853. Xtrack. C major is the default key in every track before the first 
  3854. XSID_KeySig SEvent.
  3855. X
  3856. XDynamic Mark SEvent
  3857. X
  3858. XAn SEvent SID_Dynamic represents a dynamic mark like ppp and fff in 
  3859. XCommon Music Notation. Its data field is a MIDI key velocity number 
  3860. X0 through 127. This sets a "volume control" for following notes in 
  3861. Xthe track. This "track volume control" is scaled by the overall score 
  3862. Xvolume in the SHDR chunk.
  3863. X
  3864. XThe default dynamic level is 127 (full volume).
  3865. X
  3866. XSet MIDI Channel SEvent
  3867. X
  3868. XThe SEvent SID_MIDI_Chnl is for recorder programs to record the set-MIDI-channe
  3869. Xl low level event. The data byte contains a MIDI channel number. Other 
  3870. Xprograms should use instrument registers instead.
  3871. X
  3872. XSet MIDI Preset SEvent
  3873. X
  3874. XThe SEvent SID_MIDI_Preset is for recorder programs to record the 
  3875. Xset-MIDI-preset low level event. The data byte contains a MIDI preset 
  3876. Xnumber. Other programs should use instrument registers instead.
  3877. X
  3878. XInstant Music Private SEvents
  3879. X
  3880. XSixteen SEvents are used for private data for the Instant Music program. 
  3881. XSID values 144 through 159 are reserved for this purpose. Other programs 
  3882. Xshould skip over these SEvents.
  3883. X
  3884. XEnd-Mark SEvent
  3885. X
  3886. XThe SEvent type SID_Mark is reserved for an end marker in working 
  3887. Xmemory. This event is never stored in a file. It may be useful if 
  3888. Xyou decide to use the filed TRAK format intact in working memory.
  3889. X
  3890. XMore SEvents To Be Defined
  3891. X
  3892. XMore SEvents can be defined in the future. The sID codes 133 through 
  3893. X143 and 160 through 254 are reserved for future needs. Caution: sID 
  3894. Xcodes must be allocated by a central "clearinghouse" to avoid conflicts. 
  3895. XWhen this SMUS standard passes the "draft" state, Commodore-Amiga 
  3896. Xwill be in charge of this activity.
  3897. X
  3898. XThe following SEvent types are under consideration and should not 
  3899. Xyet be used.
  3900. X
  3901. XIssue: A "change tempo" SEvent changes tempo during a score. Changing 
  3902. Xthe tempo affects all tracks, not just the track containing the change 
  3903. Xtempo event.
  3904. X
  3905. XOne possibility is a "scale tempo" SEvent SID_ScaleTempo that rescales 
  3906. Xthe global tempo:
  3907. XcurrentTempo := globalTempo * (data + 1) / 128
  3908. X
  3909. XThis can scale the global tempo (in the SHDR) anywhere from x1/128 
  3910. Xto x2 in roughly 1% increments.
  3911. X
  3912. XAn alternative is two events SID_SetHTempo and SID_SetLTempo. SID_SetHTempo 
  3913. Xgives the high byte and SID_SetLTempo gives the low byte of a new 
  3914. Xtempo setting, in 128ths quarter note/minute. SetHTempo automatically 
  3915. Xsets the low byte to 0, so the SetLTempo event isn't needed for course 
  3916. Xsettings. In this scheme, the SHDR's tempo is simply a starting tempo.
  3917. X
  3918. XAn advantage of SID_ScaleTempo is that the playback program can just 
  3919. Xalter the global tempo to adjust the overall performance time and 
  3920. Xstill easily implement tempo variations during the score. But the 
  3921. X"set tempo" SEvent may be simpler to generate.
  3922. X
  3923. XIssue: The events SID_BeginRepeat and SID_EndRepeat define a repeat 
  3924. Xspan for one track. The span of events between a BeginRepeat and an 
  3925. XEndRepeat is played twice. The SEvent.data field in the BeginRepeat 
  3926. Xevent could give an iteration count,1 through 255 times or 0 for "repeat 
  3927. Xforever".
  3928. X
  3929. XRepeat spans can be nested. All repeat spans automatically end at 
  3930. Xthe end of the track.
  3931. X
  3932. XAn event SID_Ending begins a section like "first ending" or "second 
  3933. Xending". The SEvent.data field gives the ending number. This SID_Ending 
  3934. Xevent only applies to the innermost repeat group. (Consider generalizing 
  3935. Xit.)
  3936. X
  3937. XA more general alternative is a "subtrack" or "subscore" event. A 
  3938. X"subtrack" event is essentially a "subroutine call" to another series 
  3939. Xof SEvents. This is a nice way to encode all the possible variations 
  3940. Xof repeats, first endings, codas, and such.
  3941. X
  3942. XTo define a subtrack, we must demark its start and end. One possibility 
  3943. Xis to define a relative brach-to-subtrack event SID_BSR and a return-from-subtr
  3944. Xack event SID_RTS. The 8-bit data field in the SID_BSR event can reach 
  3945. Xas far as 512 SEvents. A second possibility is to call a subtrack 
  3946. Xby index number, with an IFF chunk outside the TRAK defining the start 
  3947. Xand end of all subtracks. This is very general since a portion of 
  3948. Xone subtrack can be used as another subtrack. It also models the tape 
  3949. Xrecording practice of first "laying down a track" and then selecting 
  3950. Xportions of it to play and repeat. To embody the music theory idea 
  3951. Xof playing a sequence like "ABBA", just compose the "main" track entirely 
  3952. Xof subtrack events. A third possibility is to use a numbered subtrack 
  3953. Xchunk "STRK" for each subroutine.
  3954. X
  3955. X
  3956. X
  3957. X
  3958. X4. Private Chunks
  3959. X
  3960. XAs in any IFF FORM, there can be private chunks in a FORM SMUS that 
  3961. Xare designed for one particular program to store its private information. 
  3962. XAll IFF reader programs skip over unrecognized chunks, so the presense 
  3963. Xof private chunks can't hurt.
  3964. X
  3965. XInstant Music stores some global score information in a chunk of ID 
  3966. X"IRev".
  3967. X
  3968. X
  3969. X
  3970. XAppendix A. Quick Reference
  3971. X
  3972. XType Definitions
  3973. X
  3974. XHere's a collection of the C type definitions in this memo. In the 
  3975. X"struct" type definitions, fields are filed in the order shown. A 
  3976. XUBYTE field is packed into an 8-bit byte. Programs should set all 
  3977. X"pad" fields to 0.
  3978. X
  3979. X#define ID_SMUS MakeID('S', 'M', 'U', 'S')
  3980. X#define ID_SHDR MakeID('S', 'H', 'D', 'R')
  3981. X
  3982. Xtypedef struct {
  3983. X    UWORD tempo;    /* tempo, 128ths quarter note/minute    */
  3984. X    UBYTE volume;    /* overall playback volume 0 through 127    */
  3985. X    UBYTE ctTrack;    /* count of tracks in the score    */
  3986. X    } SScoreHeader;
  3987. X
  3988. X#define ID_NAME MakeID('N', 'A', 'M', 'E')
  3989. X/* NAME chunk contains a CHAR[], the musical score's name.    */
  3990. X
  3991. X#define ID_Copyright MakeID('(', 'c', ')', ' ')
  3992. X/* "(c) " chunk contains a CHAR[], the FORM's copyright notice.    */
  3993. X
  3994. X#define ID_AUTH MakeID('A', 'U', 'T', 'H')
  3995. X/* AUTH chunk contains a CHAR[], the name of the score's author.    */
  3996. X
  3997. X#define ID_ANNO MakeID('A', 'N', 'N', 'O')
  3998. X/* ANNO chunk contains a CHAR[], author's text annotations.    */
  3999. X
  4000. X#define ID_INS1 MakeID('I', 'N', 'S', '1')
  4001. X
  4002. X/* Values for the RefInstrument field "type".    */
  4003. X#define INS1_Name 0    /* just use the name; ignore data1, data2    */
  4004. X#define INS1_MIDI 1    /* <<data1, data2> = MIDI <<channel, preset>    */
  4005. X
  4006. Xtypedef struct {
  4007. X    UBYTE register;    /* set this instrument register number    */
  4008. X    UBYTE type;    /* instrument reference type    */
  4009. X    UBYTE data1, data2;    /* depends on the "type" field    */
  4010. X    CHAR  name[];    /* instrument name    */
  4011. X    } RefInstrument;
  4012. X
  4013. X#define ID_TRAK MakeID('T', 'R', 'A', 'K')
  4014. X/* TRAK chunk contains an SEvent[].    */
  4015. X
  4016. X/* SEvent: Simple musical event.    */
  4017. Xtypedef struct {
  4018. X    UBYTE sID;    /* SEvent type code    */
  4019. X    UBYTE data;    /* sID-dependent data    */
  4020. X    } SEvent;
  4021. X
  4022. X/* SEvent type codes "sID".        */
  4023. X#define SID_FirstNote     0
  4024. X#define SID_LastNote    127    /* sIDs in the range SID_FirstNote through
  4025. X                  * SID_LastNote (sign bit = 0) are notes. The 
  4026. X                 * sID is the MIDI tone number (pitch).    */
  4027. X#define SID_Rest        128    /* a rest (same data format as a note).    */
  4028. X
  4029. X#define SID_Instrument  129    /* set instrument number for this 
  4030. Xtrack.    */
  4031. X#define SID_TimeSig     130    /* set time signature for this track.    */
  4032. X#define SID_KeySig      131    /* set key signature for this track.    */
  4033. X#define SID_Dynamic     132    /* set volume for this track.    */
  4034. X#define SID_MIDI_Chnl   133    /* set MIDI channel number (sequencers)    */
  4035. X#define SID_MIDI_Preset 134    /* set MIDI preset number (sequencers)    */
  4036. X
  4037. X/* SID values 144 through 159: reserved for Instant Music SEvents.    */
  4038. X
  4039. X/* Remaining sID values up through 254: reserved for future
  4040. X * standardization.        */
  4041. X
  4042. X#define SID_Mark        255    /* sID reserved for an end-mark in RAM.    */
  4043. X
  4044. X/* SID_FirstNote..SID_LastNote, SID_Rest SEvents    */
  4045. Xtypedef struct {
  4046. X    UBYTE    tone;    /* MIDI tone number 0 to 127; 128 = rest    */
  4047. X    unsigned chord    :1,    /* 1 = a chorded note    */
  4048. X        tieOut   :1,    /* 1 = tied to the next note or chord    */
  4049. X        nTuplet  :2,    /* 0 = none, 1 = triplet, 2 = quintuplet,
  4050. X             * 3 = septuplet    */
  4051. X        dot      :1,    /* dotted note; multiply duration by 3/2    */
  4052. X        division :3;    /* basic note duration is 2-division: 0 = whole
  4053. X                * note, 1 = half note, 2 = quarter note, I 
  4054. X             * 7 = 128th note    */
  4055. X    } SNote;
  4056. X
  4057. X#define noteChord  (1<<<<7)    /* note is chorded to next note    */
  4058. X
  4059. X#define noteTieOut (1<<<<6)    /* tied to next note/chord    */
  4060. X
  4061. X#define noteNShift 4    /* shift count for nTuplet field    */
  4062. X#define noteN3     (1<<<<noteNShift)    /* note is a triplet    */
  4063. X#define noteN5     (2<<<<noteNShift)    /* note is a quintuplet    */
  4064. X#define noteN7     (3<<<<noteNShift)    /* note is a septuplet    */
  4065. X#define noteNMask  noteN7    /* bit mask for the nTuplet field    */
  4066. X
  4067. X#define noteDot    (1<<<<3)    /* note is dotted    */
  4068. X
  4069. X#define noteD1     0    /* whole note division    */
  4070. X#define noteD2     1    /* half note division    */
  4071. X#define noteD4     2    /* quarter note division    */
  4072. X#define noteD8     3     /* eighth note division    */
  4073. X#define noteD16    4     /* sixteenth note division    */
  4074. X#define noteD32    5     /* thirty-secondth note division    */
  4075. X#define noteD64    6     /* sixty-fourth note division    */
  4076. X#define noteD128   7     /* 1/128 note division    */
  4077. X#define noteDMask  noteD128    /* bit mask for the division field    */
  4078. X
  4079. X#define noteDurMask 0x3F    /* mask for combined duration fields    */
  4080. X
  4081. X/* SID_Instrument SEvent        */
  4082. X/* "data" value is an instrument register number 0 through 255.    */
  4083. X
  4084. X/* SID_TimeSig SEvent        */
  4085. Xtypedef struct {
  4086. X    UBYTE    type;    /* = SID_TimeSig    */
  4087. X    unsigned timeNSig :5,    /* time sig. "numerator" is timeNSig + 1 */
  4088. X        timeDSig :3;    /* time sig. "denominator" is 2timeDSig:
  4089. X               * 0 = whole note, 1 = half note, 2 = quarter      
  4090. X             * note, I 7 = 128th note    */
  4091. X    } STimeSig;
  4092. X
  4093. X#define timeNMask  0xF8    /* bit mask for the timeNSig field    */
  4094. X#define timeNShift 3    /* shift count for  timeNSig field    */
  4095. X
  4096. X#define timeDMask  0x07    /* bit mask for the timeDSig field    */
  4097. X
  4098. X/* SID_KeySig SEvent        */
  4099. X/* "data" value 0 = Cmaj; 1 through 7 = G,D,A,E,B,F#,C#;
  4100. X * 8 through 14 = F,Bb,Eb,Ab,Db,Gb,Cb.    */
  4101. X
  4102. X/* SID_Dynamic SEvent        */
  4103. X/* "data" value is a MIDI key velocity 0..127.    */
  4104. X
  4105. XSMUS Regular Expression
  4106. X
  4107. XHere's a regular expression summary of the FORM SMUS syntax. This 
  4108. Xcould be an IFF file or part of one.
  4109. X
  4110. XSMUS    ::= "FORM" #{    "SMUS" SHDR [NAME] [Copyright] [AUTH] [IRev]
  4111. X        ANNO* INS1*  TRAK*  InstrForm* }
  4112. X
  4113. XSHDR    ::= "SHDR" #{    SScoreHeader    }
  4114. XNAME    ::= "NAME" #{    CHAR*    } [0]
  4115. XCopyright    ::= "(c) " #{    CHAR*    } [0]
  4116. XAUTH    ::= "AUTH" #{    CHAR*    } [0]
  4117. XIRev    ::= "IRev" #{    ...    }
  4118. X
  4119. XANNO    ::= "ANNO" #{    CHAR*    } [0]
  4120. XINS1    ::= "INS1" #{    RefInstrument    } [0]
  4121. X
  4122. XTRAK    ::= "TRAK" #{    SEvent*    }
  4123. X
  4124. XInstrForm    ::= "FORM" #{    ...    }
  4125. X
  4126. XThe token "#" represents a ckSize LONG count of the following {braced} 
  4127. Xdata bytes. Literal items are shown in "quotes", [square bracket items] 
  4128. Xare optional, and "*" means 0 or more replications. A sometimes-needed 
  4129. Xpad byte is shown as "[0]".
  4130. X
  4131. XActually, the order of chunks in a FORM SMUS is not as strict as this 
  4132. Xregular expression indicates. The SHDR, NAME, Copyright, AUTH, IRev, 
  4133. XANNO, and INS1 chunks may appear in any order, as long as they precede 
  4134. Xthe TRAK chunks.
  4135. X
  4136. XThe chunk RInstrFormS represents any kind of instrument data FORM 
  4137. Xembedded in the FORM SMUS. For example, see the document "8SVX" IFF 
  4138. X8-Bit Sampled Voice. Of course, a recipient program will ignore an 
  4139. Xinstrument FORM if it doesn't recognize that FORM type.
  4140. X
  4141. X
  4142. X
  4143. XAppendix B. SMUS Example
  4144. X
  4145. XHere's a box diagram for a simple example, a SMUS with two instruments 
  4146. Xand two tracks. Each track contains 1 note event and 1 rest event.
  4147. X
  4148. X
  4149. X
  4150. X     +-----------------------------------------+    ------
  4151. X     |'FORM'        94               |        ^
  4152. X     |    +-----------------------------------+  |      |
  4153. X     |  |'SMUS'                    |  |        |
  4154. X     |  +-----------------------------------+  |      |
  4155. X     |    | +-------------------------------+ |  |      |
  4156. X     |    | | 'SHDR'    4          | |  |        |
  4157. X     |    | | 12800, 127, 2          | |  |      |
  4158. X     |    | +-------------------------------+ |  |      |
  4159. X     |    | +-------------------------------+ |  |      |
  4160. X     |    | | 'NAME'    10              | |  |        |
  4161. X     |    | | 'Fugue in C'          | |  |      |
  4162. X     |    | +-------------------------------+ |  |      |
  4163. X     |    | +-------------------------------+ |  |      
  4164. X     |    | | 'INS1'    9              | |  |      (94 bytes)
  4165. X     |    | | 1,0,0,0,'piano'          | |  |       
  4166. X     |    | +-------------------------------+ |  |      |
  4167. X     |    | 0                    |  |      |
  4168. X     |    | +-------------------------------+ |  |      |
  4169. X     |    | | 'INS1'    10              | |  |        |
  4170. X     |    | | 2,0,0,0,'guitar'          | |  |      |
  4171. X     |    | +-------------------------------+ |  |      |
  4172. X     |    | +-------------------------------+ |  |      |
  4173. X     |    | | 'TRAK'    4              | |  |        |
  4174. X     |    | | 60, 16, 128, 16          | |  |      |
  4175. X     |    | +-------------------------------+ |  |      |
  4176. X     |    | +-------------------------------+ |  |      |
  4177. X     |    | | 'TRAK'    4              | |  |       |
  4178. X     |    | | 128, 16, 60, 16          | |  |      |
  4179. X     |    | +-------------------------------+ |  |      |
  4180. X     |    +-----------------------------------+  |      V
  4181. X     +-----------------------------------------+    -----
  4182. X      
  4183. X
  4184. X
  4185. XAppendix B. Standards Committee
  4186. X
  4187. XThe following people contributed to the design of this IFF standard:
  4188. X
  4189. XBob "Kodiak" Burns, Commodore-Amiga
  4190. XR. J. Mical, Commodore-Amiga
  4191. XJerry Morrison, Electronic Arts
  4192. XGreg Riker, Electronic Arts
  4193. XSteve Shaw, Electronic Arts
  4194. XBarry Walsh, Commodore-Amiga
  4195. X
  4196. X
  4197. X
  4198. X
  4199. X
  4200. X
  4201. X
  4202. X
  4203. X
  4204. X
  4205. X
  4206. X
  4207. X
  4208. X
  4209. X
  4210. X
  4211. X
  4212. X
  4213. X
  4214. X
  4215. XThe "0" after the first INS1 chunk is a pad byte.
  4216. X
  4217. X
  4218. X
  4219. XAppendix C. Standards Committee
  4220. X
  4221. XThe following people contributed to the design of this SMUS standard:
  4222. X
  4223. XRalph Bellafatto, Cherry Lane Technologies
  4224. XGeoff Brown, Uhuru Sound Software
  4225. XSteve Hayes, Electronic Arts
  4226. XJerry Morrison, Electronic Arts
  4227. //END
  4228. : end of archive.
  4229. exit 0
  4230. -- 
  4231. Peter da Silva.   `-_-'
  4232. <peter@sugar.hackercorp.com>.
  4233.  
  4234.